未验证 提交 38a90c85 编写于 作者: M marregui 提交者: GitHub

feat(sql): allow comparisons between geohash and string, for chars notation (#1310)

上级 f8575182
......@@ -30,6 +30,7 @@ import io.questdb.cairo.GeoHashes;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.griffin.FunctionFactory;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.SqlExecutionContext;
import io.questdb.griffin.engine.functions.BinaryFunction;
import io.questdb.griffin.engine.functions.NegatableBooleanFunction;
......@@ -57,7 +58,7 @@ public class EqGeoHashGeoHashFunctionFactory implements FunctionFactory {
ObjList<Function> args,
IntList argPositions,
CairoConfiguration configuration,
SqlExecutionContext sqlExecutionContext) {
SqlExecutionContext sqlExecutionContext) throws SqlException {
Function geohash1 = args.getQuick(0);
Function geohash2 = args.getQuick(1);
int type1p = geohash1.getType();
......
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (c) 2014-2019 Appsicle
* Copyright (c) 2019-2020 QuestDB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.eq;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.SqlExecutionContext;
import io.questdb.griffin.engine.functions.cast.CastStrToGeoHashFunctionFactory;
import io.questdb.std.IntList;
import io.questdb.std.ObjList;
public class EqGeoHashStrFunctionFactory extends EqGeoHashGeoHashFunctionFactory {
private final static CastStrToGeoHashFunctionFactory STR2GEOHASH_FF = new CastStrToGeoHashFunctionFactory();
@Override
public String getSignature() {
return "=(GS)";
}
@Override
public Function newInstance(int position,
ObjList<Function> args,
IntList argPositions,
CairoConfiguration configuration,
SqlExecutionContext sqlExecutionContext) throws SqlException {
args.set(1, STR2GEOHASH_FF.newInstance(position, args.getQuick(0).getType(), args.getQuick(1)));
return super.newInstance(position, args, argPositions, configuration, sqlExecutionContext);
}
}
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (c) 2014-2019 Appsicle
* Copyright (c) 2019-2020 QuestDB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.eq;
import io.questdb.cairo.CairoConfiguration;
import io.questdb.cairo.sql.Function;
import io.questdb.griffin.SqlException;
import io.questdb.griffin.SqlExecutionContext;
import io.questdb.griffin.engine.functions.cast.CastStrToGeoHashFunctionFactory;
import io.questdb.std.IntList;
import io.questdb.std.ObjList;
public class EqStrGeoHashFunctionFactory extends EqGeoHashGeoHashFunctionFactory {
private final static CastStrToGeoHashFunctionFactory STR2GEOHASH_FF = new CastStrToGeoHashFunctionFactory();
@Override
public String getSignature() {
return "=(SG)";
}
@Override
public Function newInstance(int position,
ObjList<Function> args,
IntList argPositions,
CairoConfiguration configuration,
SqlExecutionContext sqlExecutionContext) throws SqlException {
args.set(0, STR2GEOHASH_FF.newInstance(position, args.getQuick(1).getType(), args.getQuick(0)));
return super.newInstance(position, args, argPositions, configuration, sqlExecutionContext);
}
}
......@@ -120,6 +120,8 @@ open module io.questdb {
io.questdb.griffin.engine.functions.eq.EqBooleanFunctionFactory,
io.questdb.griffin.engine.functions.eq.EqBinaryFunctionFactory,
io.questdb.griffin.engine.functions.eq.EqGeoHashGeoHashFunctionFactory,
io.questdb.griffin.engine.functions.eq.EqGeoHashStrFunctionFactory,
io.questdb.griffin.engine.functions.eq.EqStrGeoHashFunctionFactory,
//nullif
io.questdb.griffin.engine.functions.eq.NullIfCharCharFunctionFactory,
......
......@@ -31,6 +31,8 @@ io.questdb.griffin.engine.functions.eq.EqTimestampFunctionFactory
io.questdb.griffin.engine.functions.eq.EqBooleanFunctionFactory
io.questdb.griffin.engine.functions.eq.EqBinaryFunctionFactory
io.questdb.griffin.engine.functions.eq.EqGeoHashGeoHashFunctionFactory
io.questdb.griffin.engine.functions.eq.EqGeoHashStrFunctionFactory
io.questdb.griffin.engine.functions.eq.EqStrGeoHashFunctionFactory
#nullif
io.questdb.griffin.engine.functions.eq.NullIfCharCharFunctionFactory
......
......@@ -2036,6 +2036,38 @@ public class SqlCodeGeneratorTest extends AbstractGriffinTest {
});
}
@Test
public void testEqGeoHashWhenOtherIsStr1() throws Exception {
assertMemoryLeak(
() -> {
createGeoHashTable(4);
assertQuery("time\tuuid\thash\n" +
"2021-05-10T23:59:59.439000Z\tbbb\tewef\n",
"select * from pos where hash = 'ewef'",
"time",
true,
true,
true
);
});
}
@Test
public void testEqGeoHashWhenOtherIsStr2() throws Exception {
assertMemoryLeak(
() -> {
createGeoHashTable(4);
assertQuery("time\tuuid\thash\n" +
"2021-05-10T23:59:59.439000Z\tbbb\tewef\n",
"select * from pos where 'ewef' = hash",
"time",
true,
true,
true
);
});
}
@Test
public void testLatestByAllIndexedGeoHashTimeRange1c() throws Exception {
assertMemoryLeak(
......
......@@ -112,8 +112,8 @@ public class EqGeoHashGeoHashFunctionFactoryTest extends AbstractGriffinTest {
@Test
public void testSameTypeSameNonConstInt() {
createEqFunctionNonConstAndAssert(
(int)1E9, ColumnType.getGeoHashTypeWithBits(30),
(int)1E9, ColumnType.getGeoHashTypeWithBits(30),
(int) 1E9, ColumnType.getGeoHashTypeWithBits(30),
(int) 1E9, ColumnType.getGeoHashTypeWithBits(30),
true
);
}
......@@ -268,9 +268,9 @@ public class EqGeoHashGeoHashFunctionFactoryTest extends AbstractGriffinTest {
public void testConstHalfConst1() throws Exception {
assertMemoryLeak(() -> {
compiler.compile("create table geohash as (" +
"select " +
" cast('sp052w92p1' as GeOhAsH(50b)) geohash from long_sequence(1)" +
")",
"select " +
" cast('sp052w92p1' as GeOhAsH(50b)) geohash from long_sequence(1)" +
")",
sqlExecutionContext);
assertSql(
"geohash where cast('sp052w92p1p' as gEoHaSh(10c)) = geohash",
......@@ -392,18 +392,22 @@ public class EqGeoHashGeoHashFunctionFactoryTest extends AbstractGriffinTest {
}
private void createEqFunctionAndAssert(boolean isConstant, boolean expectedEq) {
Function func = factory.newInstance(-1, args, null, null, null);
Assert.assertEquals(expectedEq, func.getBool(null));
Assert.assertEquals(isConstant, func.isConstant());
if (func instanceof NegatableBooleanFunction) {
try {
NegatingFunctionFactory nf = new NegatingFunctionFactory("noteq", factory);
func = nf.newInstance(-1, args, null, null, null);
Assert.assertEquals(!expectedEq, func.getBool(null));
} catch (SqlException e) {
e.printStackTrace();
Assert.fail();
try {
Function func = factory.newInstance(-1, args, null, null, null);
Assert.assertEquals(expectedEq, func.getBool(null));
Assert.assertEquals(isConstant, func.isConstant());
if (func instanceof NegatableBooleanFunction) {
try {
NegatingFunctionFactory nf = new NegatingFunctionFactory("noteq", factory);
func = nf.newInstance(-1, args, null, null, null);
Assert.assertEquals(!expectedEq, func.getBool(null));
} catch (SqlException e) {
e.printStackTrace();
Assert.fail();
}
}
} catch (SqlException e) {
Assert.fail(e.getMessage());
}
}
......
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (c) 2014-2019 Appsicle
* Copyright (c) 2019-2020 QuestDB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package io.questdb.griffin.engine.functions.eq;
import io.questdb.griffin.AbstractGriffinTest;
import org.junit.Test;
public class EqGeoHashStrFunctionFactoryTest extends AbstractGriffinTest {
@Test
public void testEq1() throws Exception {
assertMemoryLeak(() -> {
compiler.compile("create table geohash as (" +
"select " +
" cast('sp052w92p1' as GeOhAsH(50b)) geohash1, " +
" cast(null as GeOhAsH(50b)) geohash2 " +
"from long_sequence(1)" +
")",
sqlExecutionContext);
assertSql(
"geohash where 'sp052w92p1' = geohash1",
"geohash1\tgeohash2\n" +
"sp052w92p1\t\n"
);
});
}
@Test
public void testEq2() throws Exception {
assertMemoryLeak(() -> {
compiler.compile("create table geohash as (" +
"select " +
" cast('sp052w92p1' as GeOhAsH(50b)) geohash1, " +
" cast(null as GeOhAsH(50b)) geohash2 " +
"from long_sequence(1)" +
")",
sqlExecutionContext);
assertSql(
"geohash where geohash1 = 'sp052w92p1'",
"geohash1\tgeohash2\n" +
"sp052w92p1\t\n"
);
});
}
@Test
public void testEq3() throws Exception {
assertMemoryLeak(() -> {
compiler.compile("create table geohash as (" +
"select " +
" cast('sp052w92p1' as GeOhAsH(50b)) geohash1, " +
" cast(null as GeOhAsH(50b)) geohash2 " +
"from long_sequence(1)" +
")",
sqlExecutionContext);
assertSql(
"geohash where geohash2 = null",
"geohash1\tgeohash2\n" +
"sp052w92p1\t\n"
);
});
}
@Test
public void testNoEq1() throws Exception {
assertMemoryLeak(() -> {
compiler.compile("create table geohash as (" +
"select " +
" cast('sp052w92p1' as GeOhAsH(50b)) geohash1, " +
" cast(null as GeOhAsH(50b)) geohash2 " +
"from long_sequence(1)" +
")",
sqlExecutionContext);
assertSql(
"geohash where 'sp052w92p0' != geohash1",
"geohash1\tgeohash2\n" +
"sp052w92p1\t\n"
);
});
}
@Test
public void testNoEq2() throws Exception {
assertMemoryLeak(() -> {
compiler.compile("create table geohash as (" +
"select " +
" cast('sp052w92p1' as GeOhAsH(50b)) geohash1, " +
" cast(null as GeOhAsH(50b)) geohash2 " +
"from long_sequence(1)" +
")",
sqlExecutionContext);
assertSql(
"geohash where geohash1 != 'sp052w92p0'",
"geohash1\tgeohash2\n" +
"sp052w92p1\t\n"
);
});
}
@Test
public void testNoEq3() throws Exception {
assertMemoryLeak(() -> {
compiler.compile("create table geohash as (" +
"select " +
" cast('sp052w92p1' as GeOhAsH(50b)) geohash1, " +
" cast(null as GeOhAsH(50b)) geohash2 " +
"from long_sequence(1)" +
")",
sqlExecutionContext);
assertSql(
"geohash where geohash2 != null",
"geohash1\tgeohash2\n"
);
});
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册