This is an automated email from the ASF dual-hosted git repository.

alexpl pushed a commit to branch sql-calcite
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/sql-calcite by this push:
     new 7b71443  IGNITE-16113 Support for BINARY/VARBINARY data types - Fixes 
#9655.
7b71443 is described below

commit 7b71443172699f3c72eab649ff660dc00b045f00
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Mon Dec 20 09:59:40 2021 +0300

    IGNITE-16113 Support for BINARY/VARBINARY data types - Fixes #9655.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../calcite/exec/exp/IgniteBuiltInMethod.java      |   9 +-
 .../query/calcite/exec/exp/IgniteSqlFunctions.java |  12 +++
 .../query/calcite/exec/exp/RexImpTable.java        |   2 +
 .../query/calcite/exec/exp/RexToLixTranslator.java |  14 +++
 .../query/calcite/exec/exp/agg/Accumulators.java   |  74 ++++++++++++++
 .../query/calcite/externalize/RelJson.java         |  18 ++++
 .../calcite/sql/fun/IgniteStdSqlOperatorTable.java |   1 +
 .../processors/query/calcite/util/TypeUtils.java   |   8 +-
 .../processors/query/calcite/DataTypesTest.java    | 104 ++++++++++++++++++++
 .../query/calcite/StdSqlOperatorsTest.java         |   4 +-
 .../calcite/exec/exp/IgniteSqlFunctionsTest.java   |   2 +-
 .../query/calcite/logical/SqlScriptRunner.java     |  24 +++--
 .../calcite/src/test/sql/types/blob/test_blob.test | 108 +++++++++++++++++++++
 .../src/test/sql/types/blob/test_blob.test_ignore  |  76 ++++++++-------
 ...t_blob_cast.test_ignore => test_blob_cast.test} |  39 ++++----
 .../test/sql/types/blob/test_blob_function.test    |  84 ++++++++++++++++
 .../sql/types/blob/test_blob_function.test_ignore  |  85 ----------------
 .../test/sql/types/blob/test_blob_operator.test    |  92 ++++++++++++++++++
 .../sql/types/blob/test_blob_operator.test_ignore  |  38 ++++----
 ...ob_string.test_ignore => test_blob_string.test} |   9 +-
 20 files changed, 630 insertions(+), 173 deletions(-)

diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteBuiltInMethod.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteBuiltInMethod.java
index 13fe07b..5187386 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteBuiltInMethod.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteBuiltInMethod.java
@@ -18,6 +18,7 @@ package 
org.apache.ignite.internal.processors.query.calcite.exec.exp;
 
 import java.lang.reflect.Method;
 
+import org.apache.calcite.avatica.util.ByteString;
 import org.apache.calcite.linq4j.tree.Types;
 import org.apache.calcite.sql.SqlIntervalQualifier;
 import org.apache.calcite.sql.parser.SqlParserUtil;
@@ -36,7 +37,13 @@ public enum IgniteBuiltInMethod {
     PARSE_INTERVAL_YEAR_MONTH(SqlParserUtil.class, "intervalToMonths", 
String.class, SqlIntervalQualifier.class),
 
     /** */
-    PARSE_INTERVAL_DAY_TIME(SqlParserUtil.class, "intervalToMillis", 
String.class, SqlIntervalQualifier.class);
+    PARSE_INTERVAL_DAY_TIME(SqlParserUtil.class, "intervalToMillis", 
String.class, SqlIntervalQualifier.class),
+
+    /** */
+    BYTESTRING_TO_STRING(IgniteSqlFunctions.class, "toString", 
ByteString.class),
+
+    /** */
+    STRING_TO_BYTESTRING(IgniteSqlFunctions.class, "toByteString", 
String.class);
 
     /** */
     public final Method method;
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
index f7c4b8b..4238dec 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
@@ -20,6 +20,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.RoundingMode;
 import org.apache.calcite.DataContext;
+import org.apache.calcite.avatica.util.ByteString;
 import org.apache.calcite.config.CalciteConnectionConfig;
 import org.apache.calcite.linq4j.AbstractEnumerable;
 import org.apache.calcite.linq4j.Enumerable;
@@ -34,6 +35,7 @@ import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.type.SqlTypeName;
 import 
org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeSystem;
+import org.apache.ignite.internal.processors.query.calcite.util.Commons;
 import org.checkerframework.checker.nullness.qual.Nullable;
 
 /**
@@ -142,6 +144,16 @@ public class IgniteSqlFunctions {
             : toBigDecimal(o.toString(), precision, scale);
     }
 
+    /** CAST(VARCHAR AS VARBINARY). */
+    public static ByteString toByteString(String s) {
+        return s == null ? null : new 
ByteString(s.getBytes(Commons.typeFactory().getDefaultCharset()));
+    }
+
+    /** CAST(VARBINARY AS VARCHAR). */
+    public static String toString(ByteString b) {
+        return b == null ? null : new String(b.getBytes(), 
Commons.typeFactory().getDefaultCharset());
+    }
+
     /** */
     private static class RangeTable implements ScannableTable {
         /** Start of the range. */
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java
index ca9da6b..9b8a77d 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java
@@ -201,6 +201,7 @@ import static 
org.apache.calcite.sql.fun.SqlStdOperatorTable.NOT;
 import static org.apache.calcite.sql.fun.SqlStdOperatorTable.NOT_EQUALS;
 import static org.apache.calcite.sql.fun.SqlStdOperatorTable.NOT_LIKE;
 import static org.apache.calcite.sql.fun.SqlStdOperatorTable.NOT_SIMILAR_TO;
+import static org.apache.calcite.sql.fun.SqlStdOperatorTable.OCTET_LENGTH;
 import static org.apache.calcite.sql.fun.SqlStdOperatorTable.OR;
 import static org.apache.calcite.sql.fun.SqlStdOperatorTable.OVERLAY;
 import static org.apache.calcite.sql.fun.SqlStdOperatorTable.PI;
@@ -269,6 +270,7 @@ public class RexImpTable {
         defineMethod(TRANSLATE3, BuiltInMethod.TRANSLATE3.method, 
NullPolicy.STRICT);
         defineMethod(CHR, "chr", NullPolicy.STRICT);
         defineMethod(CHAR_LENGTH, BuiltInMethod.CHAR_LENGTH.method, 
NullPolicy.STRICT);
+        defineMethod(OCTET_LENGTH, BuiltInMethod.OCTET_LENGTH.method, 
NullPolicy.STRICT);
         defineMethod(CONCAT, BuiltInMethod.STRING_CONCAT.method, 
NullPolicy.STRICT);
         defineMethod(CONCAT_FUNCTION, 
BuiltInMethod.MULTI_STRING_CONCAT.method, NullPolicy.STRICT);
         defineMethod(OVERLAY, BuiltInMethod.OVERLAY.method, NullPolicy.STRICT);
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexToLixTranslator.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexToLixTranslator.java
index 7439e34..9962507 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexToLixTranslator.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexToLixTranslator.java
@@ -502,6 +502,12 @@ public class RexToLixTranslator implements 
RexVisitor<RexToLixTranslator.Result>
                                 BuiltInMethod.BOOLEAN_TO_STRING.method,
                                 operand));
                         break;
+                    case BINARY:
+                    case VARBINARY:
+                        convert = RexImpTable.optimize2(
+                            operand,
+                            
Expressions.call(IgniteBuiltInMethod.BYTESTRING_TO_STRING.method, operand));
+                        break;
                 }
                 break;
             case INTERVAL_YEAR:
@@ -537,6 +543,14 @@ public class RexToLixTranslator implements 
RexVisitor<RexToLixTranslator.Result>
                             )
                         );
                 }
+                break;
+            case BINARY:
+            case VARBINARY:
+                switch (sourceType.getSqlTypeName().getFamily()) {
+                    case CHARACTER:
+                        convert = 
Expressions.call(IgniteBuiltInMethod.STRING_TO_BYTESTRING.method, operand);
+                }
+                break;
         }
         if (targetType.getSqlTypeName() == SqlTypeName.DECIMAL)
             convert = ConverterUtils.convertToDecimal(operand, targetType);
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/Accumulators.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/Accumulators.java
index 8ee774c..5f698a5 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/Accumulators.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/Accumulators.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.function.Supplier;
+import org.apache.calcite.avatica.util.ByteString;
 import org.apache.calcite.rel.core.AggregateCall;
 import org.apache.calcite.rel.type.RelDataType;
 import 
org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
@@ -34,6 +35,7 @@ import static org.apache.calcite.sql.type.SqlTypeName.BIGINT;
 import static org.apache.calcite.sql.type.SqlTypeName.DECIMAL;
 import static org.apache.calcite.sql.type.SqlTypeName.DOUBLE;
 import static org.apache.calcite.sql.type.SqlTypeName.INTEGER;
+import static org.apache.calcite.sql.type.SqlTypeName.VARBINARY;
 import static org.apache.calcite.sql.type.SqlTypeName.VARCHAR;
 
 /**
@@ -143,6 +145,9 @@ public class Accumulators {
             case CHAR:
             case VARCHAR:
                 return VarCharMinMax.MIN_FACTORY;
+            case BINARY:
+            case VARBINARY:
+                return VarBinaryMinMax.MIN_FACTORY;
             case BIGINT:
             default:
                 return LongMinMax.MIN_FACTORY;
@@ -163,6 +168,9 @@ public class Accumulators {
             case CHAR:
             case VARCHAR:
                 return VarCharMinMax.MAX_FACTORY;
+            case BINARY:
+            case VARBINARY:
+                return VarBinaryMinMax.MAX_FACTORY;
             case BIGINT:
             default:
                 return LongMinMax.MAX_FACTORY;
@@ -865,6 +873,72 @@ public class Accumulators {
     }
 
     /** */
+    private static class VarBinaryMinMax implements Accumulator {
+        /** */
+        public static final Supplier<Accumulator> MIN_FACTORY = () -> new 
VarBinaryMinMax(true);
+
+        /** */
+        public static final Supplier<Accumulator> MAX_FACTORY = () -> new 
VarBinaryMinMax(false);
+
+        /** */
+        private final boolean min;
+
+        /** */
+        private ByteString val;
+
+        /** */
+        private boolean empty = true;
+
+        /** */
+        private VarBinaryMinMax(boolean min) {
+            this.min = min;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void add(Object... args) {
+            ByteString in = (ByteString)args[0];
+
+            if (in == null)
+                return;
+
+            val = empty ? in : min ?
+                (val.compareTo(in) < 0 ? val : in) :
+                (val.compareTo(in) < 0 ? in : val);
+
+            empty = false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void apply(Accumulator other) {
+            VarBinaryMinMax other0 = (VarBinaryMinMax)other;
+
+            if (other0.empty)
+                return;
+
+            val = empty ? other0.val : min ?
+                (val.compareTo(other0.val) < 0 ? val : other0.val) :
+                (val.compareTo(other0.val) < 0 ? other0.val : val);
+
+            empty = false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Object end() {
+            return empty ? null : val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public List<RelDataType> argumentTypes(IgniteTypeFactory 
typeFactory) {
+            return 
F.asList(typeFactory.createTypeWithNullability(typeFactory.createSqlType(VARBINARY),
 true));
+        }
+
+        /** {@inheritDoc} */
+        @Override public RelDataType returnType(IgniteTypeFactory typeFactory) 
{
+            return 
typeFactory.createTypeWithNullability(typeFactory.createSqlType(VARBINARY), 
true);
+        }
+    }
+
+    /** */
     private static class DistinctAccumulator implements Accumulator {
         /** */
         private final Accumulator acc;
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJson.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJson.java
index 45e55da..ed39cb2 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJson.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJson.java
@@ -34,6 +34,7 @@ import com.google.common.cache.LoadingCache;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import org.apache.calcite.avatica.AvaticaUtils;
+import org.apache.calcite.avatica.util.ByteString;
 import org.apache.calcite.avatica.util.TimeUnit;
 import org.apache.calcite.avatica.util.TimeUnitRange;
 import org.apache.calcite.linq4j.tree.BlockBuilder;
@@ -91,6 +92,7 @@ import org.apache.calcite.sql.SqlSyntax;
 import org.apache.calcite.sql.SqlWindow;
 import org.apache.calcite.sql.fun.SqlTrimFunction;
 import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.SqlTypeFamily;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.validate.SqlNameMatchers;
 import org.apache.calcite.util.ImmutableBitSet;
@@ -297,6 +299,8 @@ class RelJson {
             return toJson((RelDataType)value);
         else if (value instanceof RelDataTypeField)
             return toJson((RelDataTypeField)value);
+        else if (value instanceof ByteString)
+            return toJson((ByteString)value);
         else
             throw new UnsupportedOperationException("type not serializable: "
                 + value + " (type " + value.getClass().getCanonicalName() + 
")");
@@ -502,6 +506,8 @@ class RelJson {
 
                 if (type.getSqlTypeName() == SqlTypeName.SYMBOL)
                     literal = toEnum(literal);
+                else if (type.getSqlTypeName().getFamily() == 
SqlTypeFamily.BINARY)
+                    literal = toByteString(literal);
 
                 return rexBuilder.makeLiteral(literal, type, false);
             }
@@ -581,6 +587,13 @@ class RelJson {
     }
 
     /** */
+    private ByteString toByteString(Object o) {
+        assert o instanceof String;
+
+        return ByteString.of((String)o, 16);
+    }
+
+    /** */
     private RelFieldCollation toFieldCollation(Map<String, Object> map) {
         Integer field = (Integer)map.get("field");
         Direction direction = toEnum(map.get("direction"));
@@ -912,4 +925,9 @@ class RelJson {
         map.put("syntax", toJson(operator.getSyntax()));
         return map;
     }
+
+    /** */
+    private Object toJson(ByteString val) {
+        return val.toString();
+    }
 }
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/fun/IgniteStdSqlOperatorTable.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/fun/IgniteStdSqlOperatorTable.java
index 3e5dcaa..0f4e7dc 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/fun/IgniteStdSqlOperatorTable.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/fun/IgniteStdSqlOperatorTable.java
@@ -249,6 +249,7 @@ public class IgniteStdSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
         register(SqlLibraryOperators.LEAST);
         register(SqlLibraryOperators.GREATEST);
         register(SqlLibraryOperators.COMPRESS);
+        register(SqlStdOperatorTable.OCTET_LENGTH);
 
         // XML Operators.
         register(SqlLibraryOperators.EXTRACT_VALUE);
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java
index 8c7c33e..a6e0376 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java
@@ -32,6 +32,7 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import com.google.common.collect.ImmutableSet;
 import org.apache.calcite.DataContext;
+import org.apache.calcite.avatica.util.ByteString;
 import org.apache.calcite.avatica.util.DateTimeUtils;
 import org.apache.calcite.plan.RelOptSchema;
 import org.apache.calcite.plan.RelOptTable;
@@ -64,7 +65,8 @@ public class TypeUtils {
         java.sql.Time.class,
         java.sql.Timestamp.class,
         Duration.class,
-        Period.class
+        Period.class,
+        byte[].class
     );
 
     /** */
@@ -280,6 +282,8 @@ public class TypeUtils {
         }
         else if (storageType == Period.class)
             return (int)((Period)val).toTotalMonths();
+        else if (storageType == byte[].class)
+            return new ByteString((byte[])val);
         else
             return val;
     }
@@ -300,6 +304,8 @@ public class TypeUtils {
             return Duration.ofMillis((Long)val);
         else if (storageType == Period.class && val instanceof Integer)
             return Period.of((Integer)val / 12, (Integer)val % 12, 0);
+        else if (storageType == byte[].class && val instanceof ByteString)
+            return ((ByteString)val).getBytes();
         else
             return val;
     }
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/DataTypesTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/DataTypesTest.java
index 00e1072..9c8319f 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/DataTypesTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/DataTypesTest.java
@@ -18,8 +18,10 @@
 package org.apache.ignite.internal.processors.query.calcite;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 import com.google.common.collect.ImmutableSet;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.configuration.CacheConfiguration;
 import 
org.apache.ignite.internal.processors.query.calcite.integration.AbstractBasicIntegrationTest;
@@ -137,4 +139,106 @@ public class DataTypesTest extends 
AbstractBasicIntegrationTest {
             assertEquals(val.length(), rows.get(0).get(0));
         }
     }
+
+    /** */
+    @Test
+    public void testBinarySql() {
+        try {
+            executeSql("CREATE TABLE tbl(b BINARY(3), v VARBINARY)");
+
+            byte[] val = new byte[] {1, 2, 3};
+
+            // From parameters to internal, from internal to store, from store 
to internal and from internal to user.
+            executeSql("INSERT INTO tbl VALUES (?, ?)", val, val);
+
+            List<List<?>> res = executeSql("SELECT b, v FROM tbl");
+
+            assertEquals(1, res.size());
+            assertEquals(2, res.get(0).size());
+            assertTrue(Objects.deepEquals(val, res.get(0).get(0)));
+            assertTrue(Objects.deepEquals(val, res.get(0).get(1)));
+
+            executeSql("DELETE FROM tbl");
+
+            // From literal to internal, from internal to store, from store to 
internal and from internal to user.
+            executeSql("INSERT INTO tbl VALUES (x'1A2B3C', x'AABBCC')");
+
+            res = executeSql("SELECT b, v FROM tbl");
+
+            assertEquals(1, res.size());
+            assertEquals(2, res.get(0).size());
+            assertTrue(Objects.deepEquals(new byte[] {0x1A, 0x2B, 0x3C}, 
res.get(0).get(0)));
+            assertTrue(Objects.deepEquals(new byte[] {(byte)0xAA, (byte)0xBB, 
(byte)0xCC}, res.get(0).get(1)));
+        }
+        finally {
+            executeSql("DROP TABLE IF EXISTS tbl");
+        }
+    }
+
+    /** Cache API - SQL API cross check. */
+    @Test
+    public void testBinaryCache() {
+        try {
+            IgniteCache<Integer, byte[]> cache = client.getOrCreateCache(new 
CacheConfiguration<Integer, byte[]>()
+                .setName("binary_cache")
+                .setSqlSchema("PUBLIC")
+                .setQueryEntities(F.asList(new QueryEntity(Integer.class, 
byte[].class).setTableName("binary_table")))
+            );
+
+            byte[] val = new byte[] {1, 2, 3};
+
+            // From cache to internal, from internal to user.
+            cache.put(1, val);
+
+            List<List<?>> res = executeSql("SELECT _val FROM binary_table");
+            assertEquals(1, res.size());
+            assertEquals(1, res.get(0).size());
+            assertTrue(Objects.deepEquals(val, res.get(0).get(0)));
+
+            // From literal to internal, from internal to cache.
+            executeSql("INSERT INTO binary_table (_KEY, _VAL) VALUES (2, 
x'010203')");
+            byte[] resVal = cache.get(2);
+            assertTrue(Objects.deepEquals(val, resVal));
+        }
+        finally {
+            client.destroyCache("binary_cache");
+        }
+    }
+
+    /** */
+    @Test
+    public void testBinaryAggregation() {
+        try {
+            executeSql("CREATE TABLE tbl(b varbinary)");
+            executeSql("INSERT INTO tbl VALUES (NULL)");
+            executeSql("INSERT INTO tbl VALUES (x'010203')");
+            executeSql("INSERT INTO tbl VALUES (x'040506')");
+            List<List<?>> res = executeSql("SELECT MIN(b), MAX(b) FROM tbl");
+
+            assertEquals(1, res.size());
+            assertEquals(2, res.get(0).size());
+            assertTrue(Objects.deepEquals(new byte[] {1, 2, 3}, 
res.get(0).get(0)));
+            assertTrue(Objects.deepEquals(new byte[] {4, 5, 6}, 
res.get(0).get(1)));
+        }
+        finally {
+            executeSql("DROP TABLE IF EXISTS tbl");
+        }
+    }
+
+    /** */
+    @Test
+    public void testBinaryConcat() {
+        try {
+            executeSql("CREATE TABLE tbl(b varbinary)");
+            executeSql("INSERT INTO tbl VALUES (x'010203')");
+            List<List<?>> res = executeSql("SELECT b || x'040506' FROM tbl");
+
+            assertEquals(1, res.size());
+            assertEquals(1, res.get(0).size());
+            assertTrue(Objects.deepEquals(new byte[] {1, 2, 3, 4, 5, 6}, 
res.get(0).get(0)));
+        }
+        finally {
+            executeSql("DROP TABLE IF EXISTS tbl");
+        }
+    }
 }
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/StdSqlOperatorsTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/StdSqlOperatorsTest.java
index 467a75e..f6db6b5 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/StdSqlOperatorsTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/StdSqlOperatorsTest.java
@@ -23,7 +23,6 @@ import java.sql.Timestamp;
 import java.time.Period;
 import java.util.Arrays;
 import java.util.Collections;
-import org.apache.calcite.avatica.util.ByteString;
 import 
org.apache.ignite.internal.processors.query.calcite.integration.AbstractBasicIntegrationTest;
 import 
org.apache.ignite.internal.processors.query.calcite.sql.fun.IgniteStdSqlOperatorTable;
 import org.apache.ignite.internal.util.typedef.F;
@@ -138,7 +137,7 @@ public class StdSqlOperatorsTest extends 
AbstractBasicIntegrationTest {
         assertQuery("SELECT LOWER('aA')").returns("aa").check();
         assertQuery("SELECT INITCAP('aA')").returns("Aa").check();
         assertQuery("SELECT TO_BASE64('aA')").returns("YUE=").check();
-        assertQuery("SELECT FROM_BASE64('YUE=')").returns(new ByteString(new 
byte[] {'a', 'A'})).check();
+        assertQuery("SELECT 
FROM_BASE64('YUE=')::VARCHAR").returns("aA").check();
         assertQuery("SELECT 
MD5('aa')").returns("4124bc0a9335c27f086f24ba207a4912").check();
         assertQuery("SELECT 
SHA1('aa')").returns("e0c9035898dd52fc65c41454cec9c4d2611bfb37").check();
         assertQuery("SELECT SUBSTRING('aAaA', 2, 2)").returns("Aa").check();
@@ -274,6 +273,7 @@ public class StdSqlOperatorsTest extends 
AbstractBasicIntegrationTest {
         assertQuery("SELECT LEAST('a', 'b')").returns("a").check();
         assertQuery("SELECT GREATEST('a', 'b')").returns("b").check();
         assertQuery("SELECT COMPRESS('')::VARCHAR").returns("").check();
+        assertQuery("SELECT OCTET_LENGTH(x'01')").returns(1).check();
     }
 
     /** */
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctionsTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctionsTest.java
index 90cf6f9..b6c1e4a 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctionsTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctionsTest.java
@@ -28,7 +28,7 @@ public class IgniteSqlFunctionsTest {
     /** */
     @Test
     public void testBigDecimalToString() {
-        Assert.assertNull(IgniteSqlFunctions.toString(null));
+        Assert.assertNull(IgniteSqlFunctions.toString((BigDecimal)null));
 
         Assert.assertEquals(
             "10",
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/logical/SqlScriptRunner.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/logical/SqlScriptRunner.java
index 9ff891d..af8105b 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/logical/SqlScriptRunner.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/logical/SqlScriptRunner.java
@@ -39,6 +39,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import com.google.common.collect.ImmutableSet;
+import org.apache.calcite.avatica.util.ByteString;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cache.query.FieldsQueryCursor;
@@ -73,8 +74,8 @@ public class SqlScriptRunner {
         int rows = r1.size();
 
         for (int i = 0; i < rows; ++i) {
-            String s1 = String.valueOf(r1.get(i));
-            String s2 = String.valueOf(r2.get(i));
+            String s1 = toString(r1.get(i));
+            String s2 = toString(r2.get(i));
 
             if (!s1.equals(s2))
                 return s1.compareTo(s2);
@@ -156,6 +157,14 @@ public class SqlScriptRunner {
     }
 
     /** */
+    private static String toString(Object res) {
+        if (res instanceof byte[])
+            return ByteString.toString((byte[])res, 16);
+        else
+            return String.valueOf(res);
+    }
+
+    /** */
     private class Script implements Iterable<Command>, AutoCloseable {
         /** Reader. */
         private final String fileName;
@@ -611,7 +620,10 @@ public class SqlScriptRunner {
                 for (int j = 0; j < expectedRow.size(); ++j) {
                     checkEquals("Not expected result at: " + posDesc +
                         ". [row=" + i + ", col=" + j +
-                        ", expected=" + expectedRow.get(j) + ", actual=" + 
row.get(j) + ']', expectedRow.get(j), row.get(j));
+                        ", expected=" + expectedRow.get(j) + ", actual=" + 
SqlScriptRunner.toString(row.get(j)) + ']',
+                        expectedRow.get(j),
+                        row.get(j)
+                    );
                 }
             }
         }
@@ -638,8 +650,8 @@ public class SqlScriptRunner {
                 }
             }
             else {
-                if 
(!String.valueOf(expectedStr).equals(String.valueOf(actual)) &&
-                    !("(empty)".equals(expectedStr) && 
String.valueOf(actual).isEmpty()))
+                if 
(!String.valueOf(expectedStr).equals(SqlScriptRunner.toString(actual)) &&
+                    !("(empty)".equals(expectedStr) && 
SqlScriptRunner.toString(actual).isEmpty()))
                      throw new AssertionError(msg);
             }
         }
@@ -652,7 +664,7 @@ public class SqlScriptRunner {
 
             for (List<?> row : res) {
                 for (Object col : row) {
-                    messageDigest.update(String.valueOf(col).getBytes());
+                    
messageDigest.update(SqlScriptRunner.toString(col).getBytes());
                     messageDigest.update(NL_BYTES);
                 }
             }
diff --git a/modules/calcite/src/test/sql/types/blob/test_blob.test 
b/modules/calcite/src/test/sql/types/blob/test_blob.test
new file mode 100644
index 0000000..be0647a
--- /dev/null
+++ b/modules/calcite/src/test/sql/types/blob/test_blob.test
@@ -0,0 +1,108 @@
+# name: test/sql/types/blob/test_blob.test
+# description: BLOB tests
+# group: [blob]
+
+statement ok
+PRAGMA enable_verification
+
+statement ok
+CREATE TABLE blobs (b varbinary);
+
+# Insert valid hex strings
+statement ok
+INSERT INTO blobs VALUES(x'aaffaa'), (x'AAFFAAAAFFAA'), (x'AAFFAAAAFFAAAAFFAA')
+
+query T rowsort
+SELECT * FROM blobs
+----
+aaffaa
+aaffaaaaffaa
+aaffaaaaffaaaaffaa
+
+# Insert valid hex strings, lower case
+statement ok
+DELETE FROM blobs
+
+statement ok
+INSERT INTO blobs VALUES(x'aaffaa'), (x'aaffaaaaffaa'), (x'aaffaaaaffaaaaffaa')
+
+query T rowsort
+SELECT * FROM blobs
+----
+aaffaa
+aaffaaaaffaa
+aaffaaaaffaaaaffaa
+
+# Insert valid hex strings with number and letters
+statement ok
+DELETE FROM blobs
+
+statement ok
+INSERT INTO blobs VALUES(x'aa1199'), (x'aa1199aa1199'), (x'aa1199aa1199aa1199')
+
+query T rowsort
+SELECT * FROM blobs
+----
+aa1199
+aa1199aa1199
+aa1199aa1199aa1199
+
+# Insert invalid hex strings (invalid hex chars: G, H, I)
+statement error
+INSERT INTO blobs VALUES(x'GAFFAA')
+
+# Insert invalid hex strings (odd # of chars)
+statement error
+INSERT INTO blobs VALUES(x'A')
+
+statement error
+INSERT INTO blobs VALUES(x'AAA')
+
+statement ok
+DELETE FROM blobs
+
+# Implicit cast
+statement ok
+INSERT INTO blobs VALUES('blablabla')
+
+# BINARY with “non-printable” octets
+statement ok
+INSERT INTO blobs VALUES('abc �'::VARBINARY)
+
+query T
+SELECT b::varchar FROM blobs ORDER BY b
+----
+abc �
+blablabla
+
+# BINARY null and empty values
+query T
+SELECT ''::VARBINARY
+----
+(empty)
+
+query T
+SELECT NULL::VARBINARY
+----
+NULL
+
+statement ok
+CREATE TABLE blob_empty (b binary);
+
+statement ok
+INSERT INTO blob_empty VALUES('')
+
+statement ok
+INSERT INTO blob_empty VALUES(''::VARBINARY)
+
+statement ok
+INSERT INTO blob_empty VALUES(NULL), (NULL::VARBINARY)
+
+query T rowsort
+SELECT * FROM blob_empty
+----
+NULL
+NULL
+(empty)
+(empty)
+
diff --git a/modules/calcite/src/test/sql/types/blob/test_blob.test_ignore 
b/modules/calcite/src/test/sql/types/blob/test_blob.test_ignore
index d0769d8..f0fca68 100644
--- a/modules/calcite/src/test/sql/types/blob/test_blob.test_ignore
+++ b/modules/calcite/src/test/sql/types/blob/test_blob.test_ignore
@@ -1,79 +1,89 @@
 # name: test/sql/types/blob/test_blob.test
 # description: BLOB tests
 # group: [blob]
-# Ignore https://issues.apache.org/jira/browse/IGNITE-15618
+# Ignore https://issues.apache.org/jira/browse/IGNITE-15123
 
 statement ok
 PRAGMA enable_verification
 
 statement ok
-CREATE TABLE blobs (b binary);
+CREATE TABLE blobs (b varbinary);
 
 # Insert valid hex strings
 statement ok
-INSERT INTO blobs VALUES('\xaa\xff\xaa'), ('\xAA\xFF\xAA\xAA\xFF\xAA'), 
('\xAA\xFF\xAA\xAA\xFF\xAA\xAA\xFF\xAA')
+INSERT INTO blobs VALUES(x'aaffaa'), (x'AAFFAAAAFFAA'), (x'AAFFAAAAFFAAAAFFAA')
 
-query T
+query T rowsort
 SELECT * FROM blobs
 ----
-\xAA\xFF\xAA
-\xAA\xFF\xAA\xAA\xFF\xAA
-\xAA\xFF\xAA\xAA\xFF\xAA\xAA\xFF\xAA
+aaffaa
+aaffaaaaffaa
+aaffaaaaffaaaaffaa
 
 # Insert valid hex strings, lower case
 statement ok
 DELETE FROM blobs
 
 statement ok
-INSERT INTO blobs VALUES('\xaa\xff\xaa'), ('\xaa\xff\xaa\xaa\xff\xaa'), 
('\xaa\xff\xaa\xaa\xff\xaa\xaa\xff\xaa')
+INSERT INTO blobs VALUES(x'aaffaa'), (x'aaffaaaaffaa'), (x'aaffaaaaffaaaaffaa')
 
-query T
+query T rowsort
 SELECT * FROM blobs
 ----
-\xAA\xFF\xAA
-\xAA\xFF\xAA\xAA\xFF\xAA
-\xAA\xFF\xAA\xAA\xFF\xAA\xAA\xFF\xAA
+aaffaa
+aaffaaaaffaa
+aaffaaaaffaaaaffaa
 
 # Insert valid hex strings with number and letters
 statement ok
 DELETE FROM blobs
 
 statement ok
-INSERT INTO blobs VALUES('\xaa1199'), ('\xaa1199aa1199'), 
('\xaa1199aa1199aa1199')
+INSERT INTO blobs VALUES(x'aa1199'), (x'aa1199aa1199'), (x'aa1199aa1199aa1199')
 
-query T
+query T rowsort
 SELECT * FROM blobs
 ----
-\xAA1199
-\xAA1199aa1199
-\xAA1199aa1199aa1199
+aa1199
+aa1199aa1199
+aa1199aa1199aa1199
 
 # Insert invalid hex strings (invalid hex chars: G, H, I)
 statement error
-INSERT INTO blobs VALUES('\xGA\xFF\xAA')
+INSERT INTO blobs VALUES(x'GAFFAA')
 
 # Insert invalid hex strings (odd # of chars)
 statement error
-INSERT INTO blobs VALUES('\xA')
+INSERT INTO blobs VALUES(x'A')
 
 statement error
-INSERT INTO blobs VALUES('\xAA\xA')
+INSERT INTO blobs VALUES(x'AAA')
 
-statement error
-INSERT INTO blobs VALUES('blablabla\x')
+statement ok
+DELETE FROM blobs
 
-# BLOB with “non-printable” octets
-statement error
-SELECT 'abc �'::BYTEA;
+# Implicit cast
+statement ok
+INSERT INTO blobs VALUES('blablabla')
+
+# BINARY with “non-printable” octets
+statement ok
+INSERT INTO blobs VALUES('abc �'::VARBINARY)
 
-# BLOB null and empty values
 query T
-SELECT ''::BLOB
+SELECT b::varchar FROM blobs ORDER BY b
+----
+abc �
+blablabla
+
+# BINARY null and empty values
+query T
+SELECT ''::VARBINARY
 ----
 (empty)
 
 query T
-SELECT NULL::BLOB
+SELECT NULL::VARBINARY
 ----
 NULL
 
@@ -81,16 +91,16 @@ statement ok
 CREATE TABLE blob_empty (b binary);
 
 statement ok
-INSERT INTO blob_empty VALUES(''), (''::BLOB)
+INSERT INTO blob_empty VALUES(''), (''::VARBINARY)
 
 statement ok
-INSERT INTO blob_empty VALUES(NULL), (NULL::BLOB)
+INSERT INTO blob_empty VALUES(NULL), (NULL::VARBINARY)
 
-query T
+query T rowsort
 SELECT * FROM blob_empty
 ----
-(empty)
-(empty)
 NULL
 NULL
+(empty)
+(empty)
 
diff --git a/modules/calcite/src/test/sql/types/blob/test_blob_cast.test_ignore 
b/modules/calcite/src/test/sql/types/blob/test_blob_cast.test
similarity index 58%
rename from modules/calcite/src/test/sql/types/blob/test_blob_cast.test_ignore
rename to modules/calcite/src/test/sql/types/blob/test_blob_cast.test
index 03eaf09..17fc157 100644
--- a/modules/calcite/src/test/sql/types/blob/test_blob_cast.test_ignore
+++ b/modules/calcite/src/test/sql/types/blob/test_blob_cast.test
@@ -1,7 +1,6 @@
 # name: test/sql/types/blob/test_blob_cast.test
 # description: Cast BLOB values
 # group: [blob]
-# Ignore https://issues.apache.org/jira/browse/IGNITE-15618
 
 statement ok
 PRAGMA enable_verification
@@ -16,57 +15,57 @@ a
 query T
 SELECT 'a'::VARCHAR::binary
 ----
-a
+61
 
 # Hex string with BLOB
 query T
-SELECT '\x20\x00\xFF'::binary
+SELECT x'2000FF'::varbinary
 ----
- \x00\xFF
+2000ff
 
 # CastFromBlob with hex string
 query T
-SELECT '\x20\x00\xFF'::BLOB::VARCHAR
+SELECT x'612061'::VARBINARY::VARCHAR
 ----
- \x00\xFF
+a a
 
 # CastFromBlob and after CastToBlob with hex string
 query T
-SELECT '\x20\x00\xFF'::BLOB::VARCHAR::BLOB
+SELECT x'612061'::VARBINARY::VARCHAR::VARBINARY
 ----
- \x00\xFF
+612061
 
 # CastFromBlob -> CastToBlob -> CastFromBlob with hex string
 query T
-SELECT '\x20\x00\xFF'::BLOB::VARCHAR::BLOB::VARCHAR
+SELECT x'612061'::VARBINARY::VARCHAR::VARBINARY::VARCHAR
 ----
- \x00\xFF
+a a
 
 # CastToBlob -> CastFromBlob -> CastToBlob with hex string
 query T
-SELECT '\x20\x00\xFF'::VARCHAR::BLOB::VARCHAR::BLOB
+SELECT x'612061'::VARCHAR::VARBINARY::VARCHAR::VARBINARY
 ----
- \x00\xFF
+612061
 
 statement error
-SELECT 1::BYTEA
+SELECT 1::VARBINARY
 
 statement error
-SELECT 1.0::BYTEA
+SELECT 1.0::VARBINARY
 
-# numeric -> bytea, not valid/implemented casts
+# numeric -> varbinary, not valid/implemented casts
 statement error
-SELECT 1::tinyint::BYTEA
+SELECT 1::tinyint::VARBINARY
 
 statement error
-SELECT 1::smallint::BYTEA
+SELECT 1::smallint::VARBINARY
 
 statement error
-SELECT 1::integer::BYTEA
+SELECT 1::integer::VARBINARY
 
 statement error
-SELECT 1::bigint::BYTEA
+SELECT 1::bigint::VARBINARY
 
 statement error
-SELECT 1::decimal::BYTEA
+SELECT 1::decimal::VARBINARY
 
diff --git a/modules/calcite/src/test/sql/types/blob/test_blob_function.test 
b/modules/calcite/src/test/sql/types/blob/test_blob_function.test
new file mode 100644
index 0000000..1633df7
--- /dev/null
+++ b/modules/calcite/src/test/sql/types/blob/test_blob_function.test
@@ -0,0 +1,84 @@
+# name: test/sql/types/blob/test_blob_function.test
+# description: BLOB with Functions
+# group: [blob]
+
+statement ok
+PRAGMA enable_verification
+
+statement ok
+CREATE TABLE blobs (b varbinary);
+
+statement ok
+INSERT INTO blobs VALUES ('a'::binary)
+
+# conventional concat
+query T
+SELECT (b || 'ZZ'::varbinary)::varchar FROM blobs
+----
+aZZ
+
+query T
+SELECT 'abc '::varbinary || 'klm *'::varbinary || x'EFBFBD'::varbinary || 
'T'::varbinary
+----
+616263206b6c6d202aefbfbd54
+
+statement ok
+INSERT INTO blobs VALUES ('abc '::varbinary || 'klm *'::varbinary || 
x'EFBFBD'::varbinary || 'T'::varbinary)
+
+query I
+SELECT COUNT(*) FROM blobs
+----
+2
+
+# octet_length
+query I
+SELECT OCTET_LENGTH(b) FROM blobs ORDER BY 1
+----
+1
+13
+
+# HEX strings
+statement ok
+DELETE FROM blobs
+
+statement ok
+INSERT INTO blobs VALUES (x'FF'::binary)
+
+query T
+SELECT b || 'ZZ'::varbinary FROM blobs
+----
+ff5a5a
+
+query T
+SELECT b || x'5A5A'::varbinary FROM blobs
+----
+ff5a5a
+
+# BLOB || VARCHAR is not allowed, should fail
+statement error
+SELECT b || '5A5A'::VARCHAR FROM blobs
+
+# Octet Length tests
+statement ok
+DELETE FROM blobs
+
+statement ok
+INSERT INTO blobs VALUES (x'FF'::binary)
+
+statement ok
+INSERT INTO blobs VALUES ('FF'::varbinary)
+
+statement ok
+INSERT INTO blobs VALUES (x'55AAFF55AAFF55AAFF01'::varbinary)
+
+statement ok
+INSERT INTO blobs VALUES ('55AAFF55AAFF55AAFF01'::varbinary)
+
+query I
+SELECT OCTET_LENGTH(b) FROM blobs ORDER BY 1
+----
+1
+2
+10
+20
+
diff --git 
a/modules/calcite/src/test/sql/types/blob/test_blob_function.test_ignore 
b/modules/calcite/src/test/sql/types/blob/test_blob_function.test_ignore
deleted file mode 100644
index 5040b6d..0000000
--- a/modules/calcite/src/test/sql/types/blob/test_blob_function.test_ignore
+++ /dev/null
@@ -1,85 +0,0 @@
-# name: test/sql/types/blob/test_blob_function.test
-# description: BLOB with Functions
-# group: [blob]
-# Ignore https://issues.apache.org/jira/browse/IGNITE-15618
-
-statement ok
-PRAGMA enable_verification
-
-statement ok
-CREATE TABLE blobs (b binary);
-
-statement ok
-INSERT INTO blobs VALUES ('a'::binary)
-
-# conventional concat
-query T
-SELECT b || 'ZZ'::binary FROM blobs
-----
-aZZ
-
-query T
-SELECT 'abc '::BYTEA || 'klm *\xEF\xBF\xBDT'::binary
-----
-abc klm *\xEF\xBF\xBDT
-
-statement ok
-INSERT INTO blobs VALUES ('abc klm *\xEF\xBF\xBDT'::binary)
-
-query I
-SELECT COUNT(*) FROM blobs
-----
-2
-
-# octet_length
-query I
-SELECT OCTET_LENGTH(b) FROM blobs
-----
-1
-13
-
-# HEX strings
-statement ok
-DELETE FROM blobs
-
-statement ok
-INSERT INTO blobs VALUES ('\xFF'::binary)
-
-query T
-SELECT b || 'ZZ'::binary FROM blobs
-----
-\xFFZZ
-
-query T
-SELECT b || '\x5A\x5A'::binary FROM blobs
-----
-\xFFZZ
-
-# BLOB || VARCHAR is not allowed, should fail
-statement error
-SELECT b || '5A5A'::VARCHAR FROM blobs
-
-# Octet Length tests
-statement ok
-DELETE FROM blobs
-
-statement ok
-INSERT INTO blobs VALUES ('\xFF'::binary)
-
-statement ok
-INSERT INTO blobs VALUES ('FF'::binary)
-
-statement ok
-INSERT INTO blobs VALUES ('\x55\xAA\xFF\x55\xAA\xFF\x55\xAA\xFF\x01'::binary)
-
-statement ok
-INSERT INTO blobs VALUES ('55AAFF55AAFF55AAFF01'::binary)
-
-query I
-SELECT OCTET_LENGTH(b) FROM blobs
-----
-1
-2
-10
-20
-
diff --git a/modules/calcite/src/test/sql/types/blob/test_blob_operator.test 
b/modules/calcite/src/test/sql/types/blob/test_blob_operator.test
new file mode 100644
index 0000000..d992760
--- /dev/null
+++ b/modules/calcite/src/test/sql/types/blob/test_blob_operator.test
@@ -0,0 +1,92 @@
+# name: test/sql/types/blob/test_blob_operator.test
+# description: Test BLOBs with various SQL operators
+# group: [blob]
+# Ignore https://issues.apache.org/jira/browse/IGNITE-15123
+
+statement ok
+PRAGMA enable_verification
+
+statement ok
+CREATE TABLE blobs (b varbinary, g INTEGER);
+
+# strings: hello -> \x68656C6C6F, r -> \x72
+statement ok
+INSERT INTO blobs VALUES ('hello', 0)
+
+statement ok
+INSERT INTO blobs VALUES (x'00' || 'whatisgoingon'::varbinary, 1)
+
+statement ok
+INSERT INTO blobs VALUES (NULL, 0)
+
+statement ok
+INSERT INTO blobs VALUES (x'FFFEFB', 1)
+
+# simple aggregates only
+query IITT
+SELECT COUNT(*), COUNT(b), MIN(b), MAX(b) FROM blobs
+----
+4      3       00776861746973676f696e676f6e    fffefb
+
+# ORDER BY
+query TI
+SELECT * FROM blobs ORDER BY b
+----
+NULL   0
+00776861746973676f696e676f6e   1
+68656c6c6f     0
+fffefb 1
+
+# GROUP BY
+statement ok
+INSERT INTO blobs VALUES ('hello', 3)
+
+statement ok
+INSERT INTO blobs VALUES (x'00' || 'whatisgoingon'::varbinary, 9)
+
+statement ok
+INSERT INTO blobs VALUES (NULL, 0)
+
+statement ok
+INSERT INTO blobs VALUES (x'FFFEFB', 19)
+
+query II
+SELECT b, SUM(g) FROM blobs GROUP BY b ORDER BY b
+----
+NULL   0
+00776861746973676f696e676f6e   10
+68656c6c6f     3
+fffefb 20
+
+# JOIN
+statement ok
+CREATE TABLE blobs2 (b VARBINARY, g INTEGER);
+
+statement ok
+INSERT INTO blobs2 VALUES ('hello', 0)
+
+statement ok
+INSERT INTO blobs2 VALUES (x'00' || 'whatisgoingon'::varbinary, 100)
+
+statement ok
+INSERT INTO blobs2 VALUES (NULL, 0)
+
+statement ok
+INSERT INTO blobs2 VALUES (x'FFFEFB', 200)
+
+# group by blobs.b, explicit JOIN
+query TR
+SELECT L.b, SUM(L.g) FROM blobs as L JOIN blobs2 AS R ON L.b=R.b GROUP BY L.b 
ORDER BY L.b
+----
+00776861746973676f696e676f6e   10.000000
+68656c6c6f     3.000000
+fffefb 20.000000
+
+# group by blobs2.b, implicit JOIN
+query TR
+SELECT R.b, SUM(R.g) FROM blobs as L, blobs2 AS R WHERE L.b=R.b GROUP BY R.b 
ORDER BY R.b
+----
+00776861746973676f696e676f6e   200.000000
+68656c6c6f     0.000000
+fffefb 400.000000
+
diff --git 
a/modules/calcite/src/test/sql/types/blob/test_blob_operator.test_ignore 
b/modules/calcite/src/test/sql/types/blob/test_blob_operator.test_ignore
index 0473de7..1fc938f 100644
--- a/modules/calcite/src/test/sql/types/blob/test_blob_operator.test_ignore
+++ b/modules/calcite/src/test/sql/types/blob/test_blob_operator.test_ignore
@@ -1,65 +1,65 @@
 # name: test/sql/types/blob/test_blob_operator.test
 # description: Test BLOBs with various SQL operators
 # group: [blob]
-# Ignore https://issues.apache.org/jira/browse/IGNITE-15618
+# Ignore https://issues.apache.org/jira/browse/IGNITE-15123
 
 statement ok
 PRAGMA enable_verification
 
 statement ok
-CREATE TABLE blobs (b binary, g INTEGER);
+CREATE TABLE blobs (b varbinary, g INTEGER);
 
 # strings: hello -> \x68656C6C6F, r -> \x72
 statement ok
-INSERT INTO blobs VALUES ('hello', 0), ('\x00whatisgoingon', 1), (NULL, 0), 
('\xFF\xFE\xFB', 1)
+INSERT INTO blobs VALUES ('hello', 0), (x'00' || 'whatisgoingon'::varbinary, 
1), (NULL, 0), (x'FFFEFB', 1)
 
 # simple aggregates only
 query IITT
 SELECT COUNT(*), COUNT(b), MIN(b), MAX(b) FROM blobs
 ----
-4      3       \x00whatisgoingon       \xFF\xFE\xFB
+4      3       00776861746973676f696e676f6e    fffefb
 
 # ORDER BY
 query TI
 SELECT * FROM blobs ORDER BY b
 ----
 NULL   0
-\x00whatisgoingon      1
-hello  0
-\xFF\xFE\xFB   1
+00776861746973676f696e676f6e   1
+68656c6c6f     0
+fffefb 1
 
 # GROUP BY
 statement ok
-INSERT INTO blobs VALUES ('hello', 3), ('\x00whatisgoingon', 9), (NULL, 0), 
('\xFF\xFE\xFB', 19)
+INSERT INTO blobs VALUES ('hello', 3), (x'00' || 'whatisgoingon'::varbinary, 
9), (NULL, 0), (x'FFFEFB', 19)
 
 query II
 SELECT b, SUM(g) FROM blobs GROUP BY b ORDER BY b
 ----
 NULL   0
-\x00whatisgoingon      10
-hello  3
-\xFF\xFE\xFB   20
+00776861746973676f696e676f6e   10
+68656c6c6f     3
+fffefb 20
 
 # JOIN
 statement ok
-CREATE TABLE blobs2 (b BYTEA, g INTEGER);
+CREATE TABLE blobs2 (b VARBINARY, g INTEGER);
 
 statement ok
-INSERT INTO blobs2 VALUES ('hello', 0), ('\x00whatisgoingon', 100), (NULL, 0), 
('\xFF\xFE\xFB', 200)
+INSERT INTO blobs2 VALUES ('hello', 0), (x'00' || 'whatisgoingon'::varbinary, 
100), (NULL, 0), (x'FFFEFB', 200)
 
 # group by blobs.b, explicit JOIN
 query TR
 SELECT L.b, SUM(L.g) FROM blobs as L JOIN blobs2 AS R ON L.b=R.b GROUP BY L.b 
ORDER BY L.b
 ----
-\x00whatisgoingon      10.000000
-hello  3.000000
-\xFF\xFE\xFB   20.000000
+00776861746973676f696e676f6e   10.000000
+68656c6c6f     3.000000
+fffefb 20.000000
 
 # group by blobs2.b, implicit JOIN
 query TR
 SELECT R.b, SUM(R.g) FROM blobs as L, blobs2 AS R WHERE L.b=R.b GROUP BY R.b 
ORDER BY R.b
 ----
-\x00whatisgoingon      200.000000
-hello  0.000000
-\xFF\xFE\xFB   400.000000
+00776861746973676f696e676f6e   200.000000
+68656c6c6f     0.000000
+fffefb 400.000000
 
diff --git 
a/modules/calcite/src/test/sql/types/blob/test_blob_string.test_ignore 
b/modules/calcite/src/test/sql/types/blob/test_blob_string.test
similarity index 80%
rename from modules/calcite/src/test/sql/types/blob/test_blob_string.test_ignore
rename to modules/calcite/src/test/sql/types/blob/test_blob_string.test
index 0214477..2dce6ea 100644
--- a/modules/calcite/src/test/sql/types/blob/test_blob_string.test_ignore
+++ b/modules/calcite/src/test/sql/types/blob/test_blob_string.test
@@ -1,20 +1,19 @@
 # name: test/sql/types/blob/test_blob_string.test
 # description: Insert BLOB values from normal strings
 # group: [blob]
-# Ignore https://issues.apache.org/jira/browse/IGNITE-15618
 
 statement ok
 PRAGMA enable_verification
 
 statement ok
-CREATE TABLE blobs (b binary);
+CREATE TABLE blobs (b varbinary);
 
-# insert BLOB from string
+# insert BINARY from string
 statement ok
-INSERT INTO blobs VALUES ('aaaaaaaaaa')
+INSERT INTO blobs VALUES ('aaaaaaaaaa'::varbinary)
 
 # sizes: 10, 100, 1000, 10000 -> double plus two due to hexadecimal 
representation
-# The concat function casts BLOB to VARCHAR,resulting in a hex string
+# The concat function casts BINARY to VARCHAR, resulting in a hex string
 statement ok
 INSERT INTO blobs SELECT b||b||b||b||b||b||b||b||b||b FROM blobs WHERE 
OCTET_LENGTH(b)=(SELECT MAX(OCTET_LENGTH(b)) FROM blobs)
 

Reply via email to