Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
jobily
Questdb
提交
29f2f452
Q
Questdb
项目概览
jobily
/
Questdb
10 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
Questdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
29f2f452
编写于
7月 26, 2021
作者:
A
Alex Pelagenko
提交者:
GitHub
7月 26, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix(sql): make SQL functions case insensitive (#1219)
上级
2d8bc4cf
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
186 addition
and
26 deletion
+186
-26
core/src/main/java/io/questdb/cairo/ColumnType.java
core/src/main/java/io/questdb/cairo/ColumnType.java
+1
-1
core/src/main/java/io/questdb/cutlass/pgwire/PGConnectionContext.java
...n/java/io/questdb/cutlass/pgwire/PGConnectionContext.java
+20
-13
core/src/main/java/io/questdb/griffin/FunctionFactoryCache.java
...rc/main/java/io/questdb/griffin/FunctionFactoryCache.java
+6
-6
core/src/main/resources/META-INF/services/io.questdb.griffin.FunctionFactory
...rces/META-INF/services/io.questdb.griffin.FunctionFactory
+1
-0
core/src/test/java/io/questdb/cutlass/pgwire/PGJobContextTest.java
...test/java/io/questdb/cutlass/pgwire/PGJobContextTest.java
+40
-2
core/src/test/java/io/questdb/griffin/DataGripTest.java
core/src/test/java/io/questdb/griffin/DataGripTest.java
+103
-0
core/src/test/java/io/questdb/griffin/FunctionParserTest.java
.../src/test/java/io/questdb/griffin/FunctionParserTest.java
+15
-4
未找到文件。
core/src/main/java/io/questdb/cairo/ColumnType.java
浏览文件 @
29f2f452
...
...
@@ -118,7 +118,7 @@ public final class ColumnType {
public
static
int
overloadDistance
(
int
from
,
int
to
)
{
// Functions cannot accept UNDEFINED type (signature is not supported)
// this check is just in case
assert
to
>=
0
;
assert
to
>=
0
:
"Undefined not supported in overloads"
;
return
overloadPriorityMatrix
[
OVERLOAD_MATRIX_SIZE
*
(
from
+
1
)
+
to
];
}
...
...
core/src/main/java/io/questdb/cutlass/pgwire/PGConnectionContext.java
浏览文件 @
29f2f452
...
...
@@ -281,6 +281,9 @@ public class PGConnectionContext implements IOContext, Mutable, WriterSource {
namedPortalMap
.
clear
();
bindVariableService
.
clear
();
bindVariableTypes
.
clear
();
resumeProcessor
=
null
;
completed
=
true
;
clearCursorAndFactory
();
}
public
void
clearWriters
()
{
...
...
@@ -2092,19 +2095,7 @@ public class PGConnectionContext implements IOContext, Mutable, WriterSource {
completed
=
maxRows
<=
0
||
rowCount
<
maxRows
;
if
(
completed
)
{
resumeProcessor
=
null
;
currentCursor
=
Misc
.
free
(
currentCursor
);
// do not free factory, it will be cached
currentFactory
=
null
;
// we we resumed the cursor send the typeAndSelect will be null
// we do not want to overwrite cache entries and potentially
// leak memory
if
(
typesAndSelect
!=
null
)
{
typesAndSelectCache
.
put
(
queryText
,
typesAndSelect
);
// clear selectAndTypes so that context doesn't accidentally
// free the factory when context finishes abnormally
this
.
typesAndSelect
=
null
;
}
clearCursorAndFactory
();
// at this point buffer can contain unsent data
// and it may not have enough space for the command
if
(
sendBufferLimit
-
sendBufferPtr
<
PROTOCOL_TAIL_COMMAND_LENGTH
)
{
...
...
@@ -2117,6 +2108,22 @@ public class PGConnectionContext implements IOContext, Mutable, WriterSource {
}
}
private
void
clearCursorAndFactory
()
{
resumeProcessor
=
null
;
currentCursor
=
Misc
.
free
(
currentCursor
);
// do not free factory, it will be cached
currentFactory
=
null
;
// we we resumed the cursor send the typeAndSelect will be null
// we do not want to overwrite cache entries and potentially
// leak memory
if
(
typesAndSelect
!=
null
)
{
typesAndSelectCache
.
put
(
queryText
,
typesAndSelect
);
// clear selectAndTypes so that context doesn't accidentally
// free the factory when context finishes abnormally
this
.
typesAndSelect
=
null
;
}
}
private
void
sendReadyForNewQuery
()
throws
PeerDisconnectedException
,
PeerIsSlowToReadException
{
prepareReadyForQuery
();
sendAndReset
();
...
...
core/src/main/java/io/questdb/griffin/FunctionFactoryCache.java
浏览文件 @
29f2f452
...
...
@@ -36,10 +36,10 @@ public class FunctionFactoryCache {
static
final
IntHashSet
invalidFunctionNameChars
=
new
IntHashSet
();
static
final
CharSequenceHashSet
invalidFunctionNames
=
new
CharSequenceHashSet
();
private
static
final
Log
LOG
=
LogFactory
.
getLog
(
FunctionFactoryCache
.
class
);
private
final
CharSequenceObjHashMap
<
ObjList
<
FunctionFactoryDescriptor
>>
factories
=
new
CharSequenceObjHashMap
<>();
private
final
CharSequenceHashSet
groupByFunctionNames
=
new
CharSequenceHashSet
();
private
final
CharSequenceHashSet
cursorFunctionNames
=
new
CharSequenceHashSet
();
private
final
CharSequenceHashSet
runtimeConstantFunctionNames
=
new
CharSequenceHashSet
();
private
final
LowerCaseCharSequenceObjHashMap
<
ObjList
<
FunctionFactoryDescriptor
>>
factories
=
new
LowerCase
CharSequenceObjHashMap
<>();
private
final
LowerCaseCharSequenceHashSet
groupByFunctionNames
=
new
LowerCase
CharSequenceHashSet
();
private
final
LowerCaseCharSequenceHashSet
cursorFunctionNames
=
new
LowerCase
CharSequenceHashSet
();
private
final
LowerCaseCharSequenceHashSet
runtimeConstantFunctionNames
=
new
LowerCase
CharSequenceHashSet
();
public
FunctionFactoryCache
(
CairoConfiguration
configuration
,
Iterable
<
FunctionFactory
>
functionFactories
)
{
boolean
enableTestFactories
=
configuration
.
enableTestFactories
();
...
...
@@ -112,11 +112,11 @@ public class FunctionFactoryCache {
return
runtimeConstantFunctionNames
.
contains
(
name
);
}
private
void
addFactoryToList
(
CharSequenceObjHashMap
<
ObjList
<
FunctionFactoryDescriptor
>>
list
,
FunctionFactory
factory
)
throws
SqlException
{
private
void
addFactoryToList
(
LowerCase
CharSequenceObjHashMap
<
ObjList
<
FunctionFactoryDescriptor
>>
list
,
FunctionFactory
factory
)
throws
SqlException
{
addFactoryToList
(
list
,
new
FunctionFactoryDescriptor
(
factory
));
}
private
void
addFactoryToList
(
CharSequenceObjHashMap
<
ObjList
<
FunctionFactoryDescriptor
>>
list
,
FunctionFactoryDescriptor
descriptor
)
{
private
void
addFactoryToList
(
LowerCase
CharSequenceObjHashMap
<
ObjList
<
FunctionFactoryDescriptor
>>
list
,
FunctionFactoryDescriptor
descriptor
)
{
String
name
=
descriptor
.
getName
();
int
index
=
list
.
keyIndex
(
name
);
ObjList
<
FunctionFactoryDescriptor
>
overload
;
...
...
core/src/main/resources/META-INF/services/io.questdb.griffin.FunctionFactory
浏览文件 @
29f2f452
...
...
@@ -466,6 +466,7 @@ io.questdb.griffin.engine.functions.catalogue.PrefixedNamespaceCatalogueFunction
io.questdb.griffin.engine.functions.catalogue.IsTableVisibleCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.UserByIdCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.TypeCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.VersionFunctionFactory
io.questdb.griffin.engine.functions.catalogue.NamespaceCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.PrefixedCurrentSchemasFunctionFactory
io.questdb.griffin.engine.functions.catalogue.CursorDereferenceFunctionFactory
...
...
core/src/test/java/io/questdb/cutlass/pgwire/PGJobContextTest.java
浏览文件 @
29f2f452
...
...
@@ -3746,6 +3746,44 @@ nodejs code:
);
}
@Test
public
void
testRowLimitNotResumed
()
throws
Exception
{
assertMemoryLeak
(()
->
{
try
(
final
PGWireServer
ignored
=
createPGServer
(
1
))
{
try
(
final
Connection
connection
=
getConnection
(
false
,
true
))
{
try
(
CallableStatement
st1
=
connection
.
prepareCall
(
"create table y as ("
+
"select timestamp_sequence(0, 1000000000) timestamp,"
+
" rnd_symbol('a','b',null) symbol1 "
+
" from long_sequence(10)"
+
") timestamp (timestamp)"
))
{
st1
.
execute
();
}
}
}
try
(
final
PGWireServer
ignored
=
createPGServer
(
1
))
{
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
try
(
final
Connection
connection
=
getConnection
(
false
,
true
))
{
try
(
PreparedStatement
select1
=
connection
.
prepareStatement
(
"select version()"
))
{
ResultSet
rs0
=
select1
.
executeQuery
();
sink
.
clear
();
assertResultSet
(
"version[VARCHAR]\n"
+
"PostgreSQL 12.3, compiled by Visual C++ build 1914, 64-bit\n"
,
sink
,
rs0
);
rs0
.
close
();
}
try
(
PreparedStatement
select2
=
connection
.
prepareStatement
(
"select timestamp from y"
))
{
select2
.
setMaxRows
(
1
);
ResultSet
rs2
=
select2
.
executeQuery
();
rs2
.
next
();
rs2
.
close
();
}
}
}
}
});
}
@Test
public
void
testStaleQueryCacheOnTableDroppedSimple
()
throws
Exception
{
testStaleQueryCacheOnTableDropped
(
true
);
...
...
@@ -3756,13 +3794,13 @@ nodejs code:
testStaleQueryCacheOnTableDropped
(
false
);
}
p
ublic
void
testStaleQueryCacheOnTableDropped
(
boolean
simple
)
throws
Exception
{
p
rivate
void
testStaleQueryCacheOnTableDropped
(
boolean
simple
)
throws
Exception
{
assertMemoryLeak
(()
->
{
try
(
final
PGWireServer
ignored
=
createPGServer
(
2
);
final
Connection
connection
=
getConnection
(
simple
,
true
)
)
{
try
(
CallableStatement
st1
=
connection
.
prepareCall
(
"create table y as ("
+
try
(
CallableStatement
st1
=
connection
.
prepareCall
(
"create table y as ("
+
"select timestamp_sequence(0, 1000000000) timestamp,"
+
" rnd_symbol('a','b',null) symbol1 "
+
" from long_sequence(10)"
+
...
...
core/src/test/java/io/questdb/griffin/DataGripTest.java
0 → 100644
浏览文件 @
29f2f452
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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
;
import
org.junit.Ignore
;
import
org.junit.Test
;
public
class
DataGripTest
extends
AbstractGriffinTest
{
@Test
@Ignore
public
void
testStartUpUnknowDBMS
()
throws
SqlException
{
assertQuery
(
""
,
"SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM,"
+
" ct.relname AS TABLE_NAME,"
+
" NOT i.indisunique AS NON_UNIQUE,"
+
" NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME,"
+
" CASE i.indisclustered"
+
" WHEN true THEN 1"
+
" ELSE CASE am.amname"
+
" WHEN 'hash' THEN 2"
+
" ELSE 3"
+
" END"
+
" END AS TYPE,"
+
" (i.keys).n AS ORDINAL_POSITION,"
+
" trim(both '\"' from pg_catalog.pg_get_indexdef(ci.oid, (i.keys).n, false)) AS COLUMN_NAME,"
+
" CASE am.amname"
+
" WHEN 'btree' THEN CASE i.indoption[(i.keys).n - 1] & 1"
+
" WHEN 1 THEN 'D'"
+
" ELSE 'A'"
+
" END"
+
" ELSE NULL"
+
" END AS ASC_OR_DESC,"
+
" ci.reltuples AS CARDINALITY,"
+
" ci.relpages AS PAGES,"
+
" pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION"
+
" FROM pg_catalog.pg_class ct"
+
" JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid)"
+
" JOIN (SELECT i.indexrelid, i.indrelid, i.indoption,"
+
" i.indisunique, i.indisclustered, i.indpred,"
+
" i.indexprs,"
+
" information_schema._pg_expandarray(i.indkey) AS keys"
+
" FROM pg_catalog.pg_index i) i"
+
" ON (ct.oid = i.indrelid)"
+
" JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid)"
+
" JOIN pg_catalog.pg_am am ON (ci.relam = am.oid)"
+
" WHERE true"
+
" AND n.nspname = E'\"public\"' AND ct.relname = E'\"xx\"'"
+
" ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION"
,
null
,
true
,
sqlExecutionContext
,
false
,
false
);
}
@Test
public
void
testUpperCaseCount
()
throws
Exception
{
assertMemoryLeak
(()
->
{
compiler
.
compile
(
"create table y as (select x from long_sequence(10))"
,
sqlExecutionContext
);
assertSql
(
"select COUNT(*) from y"
,
"count\n"
+
"10\n"
);
});
}
@Test
public
void
testLowerCaseCount
()
throws
Exception
{
assertMemoryLeak
(()
->
{
compiler
.
compile
(
"create table y as (select x from long_sequence(10))"
,
sqlExecutionContext
);
assertSql
(
"select COUNT(*) from y"
,
"count\n"
+
"10\n"
);
});
}
}
core/src/test/java/io/questdb/griffin/FunctionParserTest.java
浏览文件 @
29f2f452
...
...
@@ -41,10 +41,7 @@ import io.questdb.griffin.engine.functions.date.ToStrTimestampFunctionFactory;
import
io.questdb.griffin.engine.functions.eq.EqDoubleFunctionFactory
;
import
io.questdb.griffin.engine.functions.eq.EqIntFunctionFactory
;
import
io.questdb.griffin.engine.functions.eq.EqLongFunctionFactory
;
import
io.questdb.griffin.engine.functions.groupby.CountLong256GroupByFunctionFactory
;
import
io.questdb.griffin.engine.functions.groupby.MinDateGroupByFunctionFactory
;
import
io.questdb.griffin.engine.functions.groupby.MinFloatGroupByFunctionFactory
;
import
io.questdb.griffin.engine.functions.groupby.MinTimestampGroupByFunctionFactory
;
import
io.questdb.griffin.engine.functions.groupby.*
;
import
io.questdb.griffin.engine.functions.math.*
;
import
io.questdb.griffin.engine.functions.str.LengthStrFunctionFactory
;
import
io.questdb.griffin.engine.functions.str.LengthSymbolFunctionFactory
;
...
...
@@ -81,6 +78,7 @@ public class FunctionParserTest extends BaseFunctionFactoryTest {
ColumnType
.
overloadDistance
(
ColumnType
.
INT
,
ColumnType
.
UNDEFINED
);
Assert
.
fail
();
}
catch
(
AssertionError
e
)
{
TestUtils
.
assertContains
(
e
.
getMessage
(),
"Undefined not supported in overloads"
);
}
}
}
...
...
@@ -1110,6 +1108,19 @@ public class FunctionParserTest extends BaseFunctionFactoryTest {
});
}
@Test
public
void
testCountUpperCase
()
throws
SqlException
{
functions
.
add
(
new
CountGroupByFunctionFactory
());
final
GenericRecordMetadata
metadata
=
new
GenericRecordMetadata
();
metadata
.
add
(
new
TableColumnMetadata
(
"a"
,
ColumnType
.
INT
,
null
));
FunctionParser
functionParser
=
createFunctionParser
();
Function
function
=
parseFunction
(
"COUNT()"
,
metadata
,
functionParser
);
Assert
.
assertEquals
(
ColumnType
.
LONG
,
function
.
getType
());
Assert
.
assertEquals
(
"io.questdb.griffin.engine.functions.groupby.CountGroupByFunction"
,
function
.
getClass
().
getCanonicalName
());
}
@Test
public
void
testSymbolFunction
()
throws
SqlException
{
functions
.
add
(
new
LengthStrFunctionFactory
());
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录