Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
jobily
Questdb
提交
86062c80
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,发现更多精彩内容 >>
未验证
提交
86062c80
编写于
11月 09, 2020
作者:
J
Joan Augsburger
提交者:
GitHub
11月 09, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore(sql): column names are no longer case-sensitive
上级
f1fc3935
变更
25
隐藏空白更改
内联
并排
Showing
25 changed file
with
1871 addition
and
38 deletion
+1871
-38
core/src/main/java/io/questdb/cairo/GenericRecordMetadata.java
...src/main/java/io/questdb/cairo/GenericRecordMetadata.java
+12
-2
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java
+1
-1
core/src/main/java/io/questdb/griffin/SqlOptimiser.java
core/src/main/java/io/questdb/griffin/SqlOptimiser.java
+11
-11
core/src/main/java/io/questdb/griffin/SqlParser.java
core/src/main/java/io/questdb/griffin/SqlParser.java
+5
-5
core/src/main/java/io/questdb/griffin/SqlUtil.java
core/src/main/java/io/questdb/griffin/SqlUtil.java
+1
-1
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/AttributeCatalogueFunctionFactory.java
...unctions/catalogue/AttributeCatalogueFunctionFactory.java
+241
-0
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/IndexCatalogueCursor.java
...ffin/engine/functions/catalogue/IndexCatalogueCursor.java
+75
-0
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/IndexCatalogueFunctionFactory.java
...ne/functions/catalogue/IndexCatalogueFunctionFactory.java
+50
-0
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/InformationSchemaCursor.java
...n/engine/functions/catalogue/InformationSchemaCursor.java
+73
-0
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/InformationSchemaFunctionFactory.java
...functions/catalogue/InformationSchemaFunctionFactory.java
+50
-0
core/src/main/java/io/questdb/griffin/model/QueryModel.java
core/src/main/java/io/questdb/griffin/model/QueryModel.java
+13
-13
core/src/main/java/io/questdb/std/AbstractLowerCaseCharSequenceHashSet.java
.../io/questdb/std/AbstractLowerCaseCharSequenceHashSet.java
+174
-0
core/src/main/java/io/questdb/std/Chars.java
core/src/main/java/io/questdb/std/Chars.java
+71
-4
core/src/main/java/io/questdb/std/LowerCaseCharSequenceHashSet.java
...ain/java/io/questdb/std/LowerCaseCharSequenceHashSet.java
+103
-0
core/src/main/java/io/questdb/std/LowerCaseCharSequenceIntHashMap.java
.../java/io/questdb/std/LowerCaseCharSequenceIntHashMap.java
+147
-0
core/src/main/java/io/questdb/std/LowerCaseCharSequenceObjHashMap.java
.../java/io/questdb/std/LowerCaseCharSequenceObjHashMap.java
+162
-0
core/src/main/java/module-info.java
core/src/main/java/module-info.java
+3
-0
core/src/main/resources/META-INF/services/io.questdb.griffin.FunctionFactory
...rces/META-INF/services/io.questdb.griffin.FunctionFactory
+28
-1
core/src/test/java/io/questdb/cairo/GenericRecordMetadataTest.java
...test/java/io/questdb/cairo/GenericRecordMetadataTest.java
+25
-0
core/src/test/java/io/questdb/griffin/engine/functions/catalogue/AttributeCatalogueFunctionFactoryTest.java
...ions/catalogue/AttributeCatalogueFunctionFactoryTest.java
+231
-0
core/src/test/java/io/questdb/griffin/engine/functions/catalogue/IndexCatalogueFunctionFactoryTest.java
...unctions/catalogue/IndexCatalogueFunctionFactoryTest.java
+44
-0
core/src/test/java/io/questdb/griffin/engine/functions/catalogue/InformationSchemaFunctionFactoryTest.java
...tions/catalogue/InformationSchemaFunctionFactoryTest.java
+44
-0
core/src/test/java/io/questdb/std/LowerCaseCharSequenceHashSetTest.java
...java/io/questdb/std/LowerCaseCharSequenceHashSetTest.java
+97
-0
core/src/test/java/io/questdb/std/LowerCaseCharSequenceIntHashMapTest.java
...a/io/questdb/std/LowerCaseCharSequenceIntHashMapTest.java
+105
-0
core/src/test/java/io/questdb/std/LowerCaseCharSequenceObjHashMapTest.java
...a/io/questdb/std/LowerCaseCharSequenceObjHashMapTest.java
+105
-0
未找到文件。
core/src/main/java/io/questdb/cairo/GenericRecordMetadata.java
浏览文件 @
86062c80
...
...
@@ -25,15 +25,16 @@
package
io.questdb.cairo
;
import
io.questdb.cairo.sql.RecordMetadata
;
import
io.questdb.std.CharSequenceIntHashMap
;
import
io.questdb.std.
LowerCase
CharSequenceIntHashMap
;
import
io.questdb.std.ObjList
;
public
class
GenericRecordMetadata
extends
BaseRecordMetadata
{
public
static
final
GenericRecordMetadata
EMPTY
=
new
GenericRecordMetadata
();
private
final
LowerCaseCharSequenceIntHashMap
columnNameIndexMap
;
public
GenericRecordMetadata
()
{
this
.
columnMetadata
=
new
ObjList
<>();
this
.
columnNameIndexMap
=
new
CharSequenceIntHashMap
();
this
.
columnNameIndexMap
=
new
LowerCase
CharSequenceIntHashMap
();
this
.
timestampIndex
=
-
1
;
}
...
...
@@ -49,6 +50,15 @@ public class GenericRecordMetadata extends BaseRecordMetadata {
}
}
@Override
public
int
getColumnIndexQuiet
(
CharSequence
columnName
,
int
lo
,
int
hi
)
{
final
int
index
=
columnNameIndexMap
.
keyIndex
(
columnName
,
lo
,
hi
);
if
(
index
<
0
)
{
return
columnNameIndexMap
.
valueAt
(
index
);
}
return
-
1
;
}
public
static
GenericRecordMetadata
copyOf
(
RecordMetadata
that
)
{
GenericRecordMetadata
metadata
=
copyOfSansTimestamp
(
that
);
metadata
.
setTimestampIndex
(
that
.
getTimestampIndex
());
...
...
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java
浏览文件 @
86062c80
...
...
@@ -1050,7 +1050,7 @@ public class SqlCodeGenerator implements Mutable {
return
recordCursorFactory
;
}
try
{
final
CharSequenceIntHashMap
orderBy
=
model
.
getOrderHash
();
final
LowerCase
CharSequenceIntHashMap
orderBy
=
model
.
getOrderHash
();
final
ObjList
<
CharSequence
>
columnNames
=
orderBy
.
keys
();
final
int
size
=
columnNames
.
size
();
...
...
core/src/main/java/io/questdb/griffin/SqlOptimiser.java
浏览文件 @
86062c80
...
...
@@ -668,7 +668,7 @@ class SqlOptimiser {
// order hash is used to determine redundant order when parsing analytic function definition
private
void
createOrderHash
(
QueryModel
model
)
{
CharSequenceIntHashMap
hash
=
model
.
getOrderHash
();
LowerCase
CharSequenceIntHashMap
hash
=
model
.
getOrderHash
();
hash
.
clear
();
final
ObjList
<
ExpressionNode
>
orderBy
=
model
.
getOrderBy
();
...
...
@@ -687,7 +687,7 @@ class SqlOptimiser {
if
(
nestedModel
!=
null
)
{
createOrderHash
(
nestedModel
);
if
(
m
>
0
)
{
CharSequenceIntHashMap
thatHash
=
nestedModel
.
getOrderHash
();
LowerCase
CharSequenceIntHashMap
thatHash
=
nestedModel
.
getOrderHash
();
if
(
thatHash
.
size
()
>
0
)
{
for
(
int
i
=
0
;
i
<
m
;
i
++)
{
QueryColumn
column
=
columns
.
getQuick
(
i
);
...
...
@@ -729,7 +729,7 @@ class SqlOptimiser {
// taking into account that column is pre-aliased, e.g.
// "col, col" will look like "col, col col1"
CharSequenceObjHashMap
<
CharSequence
>
translatingAliasMap
=
translatingModel
.
getColumnNameToAliasMap
();
LowerCase
CharSequenceObjHashMap
<
CharSequence
>
translatingAliasMap
=
translatingModel
.
getColumnNameToAliasMap
();
int
index
=
translatingAliasMap
.
keyIndex
(
columnAst
.
token
);
if
(
index
<
0
)
{
// column is already being referenced by translating model
...
...
@@ -914,7 +914,7 @@ class SqlOptimiser {
}
private
ExpressionNode
doReplaceLiteral
(
@Transient
ExpressionNode
node
,
QueryModel
translatingModel
,
QueryModel
innerModel
,
QueryModel
validatingModel
)
throws
SqlException
{
final
CharSequenceObjHashMap
<
CharSequence
>
map
=
translatingModel
.
getColumnNameToAliasMap
();
final
LowerCase
CharSequenceObjHashMap
<
CharSequence
>
map
=
translatingModel
.
getColumnNameToAliasMap
();
int
index
=
map
.
keyIndex
(
node
.
token
);
if
(
index
>
-
1
)
{
// there is a possibility that column references join table, but in a different way
...
...
@@ -1210,7 +1210,7 @@ class SqlOptimiser {
return
orderByAdvice
;
}
CharSequenceObjHashMap
<
QueryColumn
>
map
=
model
.
getAliasToColumnMap
();
LowerCase
CharSequenceObjHashMap
<
QueryColumn
>
map
=
model
.
getAliasToColumnMap
();
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
QueryColumn
queryColumn
=
map
.
get
(
orderBy
.
getQuick
(
i
).
token
);
if
(
queryColumn
.
getAst
().
type
==
ExpressionNode
.
LITERAL
)
{
...
...
@@ -2277,7 +2277,7 @@ class SqlOptimiser {
if
(
ascendColumns
&&
base
!=
model
)
{
// check if column is aliased as either
// "x y" or "tab.x y" or "t.x y", where "t" is alias of table "tab"
final
CharSequenceObjHashMap
<
CharSequence
>
map
=
baseParent
.
getColumnNameToAliasMap
();
final
LowerCase
CharSequenceObjHashMap
<
CharSequence
>
map
=
baseParent
.
getColumnNameToAliasMap
();
CharSequence
alias
=
null
;
int
index
=
map
.
keyIndex
(
column
);
if
(
index
>
-
1
&&
dot
>
-
1
)
{
...
...
@@ -2496,7 +2496,7 @@ class SqlOptimiser {
if
(
flatModel
)
{
if
(
flatParent
&&
m
.
getSampleBy
()
!=
null
)
{
throw
SqlException
.
$
(
m
.
getSampleBy
().
position
,
"'sample by' must be used with 'select' clause, which contains agg
er
ate expression(s)"
);
throw
SqlException
.
$
(
m
.
getSampleBy
().
position
,
"'sample by' must be used with 'select' clause, which contains agg
reg
ate expression(s)"
);
}
}
else
{
model
.
replaceJoinModel
(
i
,
rewriteSelectClause0
(
m
));
...
...
@@ -2828,7 +2828,7 @@ class SqlOptimiser {
}
private
static
class
LiteralCheckingVisitor
implements
PostOrderTreeTraversalAlgo
.
Visitor
{
private
CharSequenceObjHashMap
<
QueryColumn
>
nameTypeMap
;
private
LowerCase
CharSequenceObjHashMap
<
QueryColumn
>
nameTypeMap
;
@Override
public
void
visit
(
ExpressionNode
node
)
{
...
...
@@ -2846,14 +2846,14 @@ class SqlOptimiser {
}
}
PostOrderTreeTraversalAlgo
.
Visitor
of
(
CharSequenceObjHashMap
<
QueryColumn
>
nameTypeMap
)
{
PostOrderTreeTraversalAlgo
.
Visitor
of
(
LowerCase
CharSequenceObjHashMap
<
QueryColumn
>
nameTypeMap
)
{
this
.
nameTypeMap
=
nameTypeMap
;
return
this
;
}
}
private
static
class
LiteralRewritingVisitor
implements
PostOrderTreeTraversalAlgo
.
Visitor
{
private
CharSequenceObjHashMap
<
CharSequence
>
aliasToColumnMap
;
private
LowerCase
CharSequenceObjHashMap
<
CharSequence
>
aliasToColumnMap
;
@Override
public
void
visit
(
ExpressionNode
node
)
{
...
...
@@ -2873,7 +2873,7 @@ class SqlOptimiser {
}
}
PostOrderTreeTraversalAlgo
.
Visitor
of
(
CharSequenceObjHashMap
<
CharSequence
>
aliasToColumnMap
)
{
PostOrderTreeTraversalAlgo
.
Visitor
of
(
LowerCase
CharSequenceObjHashMap
<
CharSequence
>
aliasToColumnMap
)
{
this
.
aliasToColumnMap
=
aliasToColumnMap
;
return
this
;
}
...
...
core/src/main/java/io/questdb/griffin/SqlParser.java
浏览文件 @
86062c80
...
...
@@ -328,7 +328,7 @@ public final class SqlParser {
return
parseSelect
(
lexer
);
}
QueryModel
parseAsSubQuery
(
GenericLexer
lexer
,
@Nullable
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
)
throws
SqlException
{
QueryModel
parseAsSubQuery
(
GenericLexer
lexer
,
@Nullable
LowerCase
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
)
throws
SqlException
{
QueryModel
model
;
this
.
subQueryMode
=
true
;
try
{
...
...
@@ -339,7 +339,7 @@ public final class SqlParser {
return
model
;
}
private
QueryModel
parseAsSubQueryAndExpectClosingBrace
(
GenericLexer
lexer
,
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
)
throws
SqlException
{
private
QueryModel
parseAsSubQueryAndExpectClosingBrace
(
GenericLexer
lexer
,
LowerCase
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
)
throws
SqlException
{
final
QueryModel
model
=
parseAsSubQuery
(
lexer
,
withClauses
);
expectTok
(
lexer
,
')'
);
return
model
;
...
...
@@ -655,7 +655,7 @@ public final class SqlParser {
return
null
;
}
private
QueryModel
parseDml
(
GenericLexer
lexer
,
@Nullable
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
)
throws
SqlException
{
private
QueryModel
parseDml
(
GenericLexer
lexer
,
@Nullable
LowerCase
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
)
throws
SqlException
{
QueryModel
model
=
null
;
QueryModel
prevModel
=
null
;
while
(
true
)
{
...
...
@@ -823,7 +823,7 @@ public final class SqlParser {
}
@NotNull
private
QueryModel
parseDml0
(
GenericLexer
lexer
,
@Nullable
CharSequenceObjHashMap
<
WithClauseModel
>
parentWithClauses
)
throws
SqlException
{
private
QueryModel
parseDml0
(
GenericLexer
lexer
,
@Nullable
LowerCase
CharSequenceObjHashMap
<
WithClauseModel
>
parentWithClauses
)
throws
SqlException
{
CharSequence
tok
;
final
int
modelPosition
=
lexer
.
getPosition
();
...
...
@@ -1274,7 +1274,7 @@ public final class SqlParser {
return
null
;
}
private
QueryModel
parseWith
(
GenericLexer
lexer
,
WithClauseModel
wcm
,
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
)
throws
SqlException
{
private
QueryModel
parseWith
(
GenericLexer
lexer
,
WithClauseModel
wcm
,
LowerCase
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
)
throws
SqlException
{
QueryModel
m
=
wcm
.
popModel
();
if
(
m
!=
null
)
{
return
m
;
...
...
core/src/main/java/io/questdb/griffin/SqlUtil.java
浏览文件 @
86062c80
...
...
@@ -81,7 +81,7 @@ public class SqlUtil {
CharacterStore
store
,
CharSequence
base
,
int
indexOfDot
,
CharSequenceObjHashMap
<
QueryColumn
>
aliasToColumnMap
LowerCase
CharSequenceObjHashMap
<
QueryColumn
>
aliasToColumnMap
)
{
final
boolean
disallowed
=
disallowedAliases
.
contains
(
base
);
...
...
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/AttributeCatalogueFunctionFactory.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.catalogue
;
import
io.questdb.cairo.*
;
import
io.questdb.cairo.sql.*
;
import
io.questdb.griffin.FunctionFactory
;
import
io.questdb.griffin.SqlExecutionContext
;
import
io.questdb.griffin.engine.functions.CursorFunction
;
import
io.questdb.std.*
;
import
io.questdb.std.str.NativeLPSZ
;
import
io.questdb.std.str.Path
;
public
class
AttributeCatalogueFunctionFactory
implements
FunctionFactory
{
private
static
final
RecordMetadata
METADATA
;
@Override
public
String
getSignature
()
{
return
"pg_catalog.pg_attribute()"
;
}
@Override
public
Function
newInstance
(
ObjList
<
Function
>
args
,
int
position
,
CairoConfiguration
configuration
)
{
return
new
CursorFunction
(
position
,
new
AttributeCatalogueCursorFactory
(
configuration
,
METADATA
)
);
}
private
static
class
AttributeCatalogueCursorFactory
extends
AbstractRecordCursorFactory
{
private
final
Path
path
=
new
Path
();
private
final
ReadOnlyColumn
metaMem
=
new
OnePageMemory
();
private
final
AttributeClassCatalogueCursor
cursor
;
public
AttributeCatalogueCursorFactory
(
CairoConfiguration
configuration
,
RecordMetadata
metadata
)
{
super
(
metadata
);
this
.
cursor
=
new
AttributeClassCatalogueCursor
(
configuration
,
path
,
metaMem
);
}
@Override
public
void
close
()
{
Misc
.
free
(
path
);
Misc
.
free
(
metaMem
);
}
@Override
public
RecordCursor
getCursor
(
SqlExecutionContext
executionContext
)
{
cursor
.
toTop
();
return
cursor
;
}
@Override
public
boolean
recordCursorSupportsRandomAccess
()
{
return
false
;
}
}
private
static
class
AttributeClassCatalogueCursor
implements
NoRandomAccessRecordCursor
{
private
final
Path
path
;
private
final
FilesFacade
ff
;
private
final
DiskReadingRecord
diskReadingRecord
=
new
DiskReadingRecord
();
private
final
NativeLPSZ
nativeLPSZ
=
new
NativeLPSZ
();
private
final
int
plimit
;
private
final
ReadOnlyColumn
metaMem
;
private
long
findFileStruct
=
0
;
private
int
columnIndex
=
0
;
private
int
tableId
=
1000
;
private
boolean
readNextFileFromDisk
=
true
;
private
int
columnCount
;
private
boolean
hasNextFile
=
true
;
private
boolean
foundMetadataFile
=
false
;
public
AttributeClassCatalogueCursor
(
CairoConfiguration
configuration
,
Path
path
,
ReadOnlyColumn
metaMem
)
{
this
.
ff
=
configuration
.
getFilesFacade
();
this
.
path
=
path
;
this
.
path
.
of
(
configuration
.
getRoot
()).
$
();
this
.
plimit
=
this
.
path
.
length
();
this
.
metaMem
=
metaMem
;
}
@Override
public
void
close
()
{
if
(
findFileStruct
!=
0
)
{
ff
.
findClose
(
findFileStruct
);
findFileStruct
=
0
;
}
metaMem
.
close
();
}
@Override
public
Record
getRecord
()
{
return
diskReadingRecord
;
}
@Override
public
boolean
hasNext
()
{
if
(
findFileStruct
==
0
)
{
findFileStruct
=
ff
.
findFirst
(
path
.
trimTo
(
plimit
).
$
());
if
(
findFileStruct
>
0
)
{
return
next0
();
}
findFileStruct
=
0
;
return
false
;
}
return
next0
();
}
@Override
public
void
toTop
()
{
if
(
findFileStruct
!=
0
)
{
ff
.
findClose
(
findFileStruct
);
findFileStruct
=
0
;
}
}
@Override
public
long
size
()
{
return
-
1
;
}
private
boolean
next0
()
{
do
{
if
(
readNextFileFromDisk
)
{
foundMetadataFile
=
false
;
final
long
pname
=
ff
.
findName
(
findFileStruct
);
if
(
hasNextFile
)
{
nativeLPSZ
.
of
(
pname
);
if
(
ff
.
findType
(
findFileStruct
)
==
Files
.
DT_DIR
&&
Chars
.
notDots
(
nativeLPSZ
)
)
{
path
.
trimTo
(
plimit
);
path
.
concat
(
pname
);
if
(
ff
.
exists
(
path
.
concat
(
TableUtils
.
META_FILE_NAME
).
$
()))
{
foundMetadataFile
=
true
;
metaMem
.
of
(
ff
,
path
,
ff
.
getPageSize
(),
ff
.
length
(
path
));
columnCount
=
metaMem
.
getInt
(
TableUtils
.
META_OFFSET_COUNT
);
tableId
=
metaMem
.
getInt
(
TableUtils
.
META_OFFSET_TABLE_ID
);
}
}
hasNextFile
=
ff
.
findNext
(
findFileStruct
)
>
0
;
}
}
if
(
foundMetadataFile
)
{
long
offset
=
TableUtils
.
getColumnNameOffset
(
columnCount
);
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
CharSequence
name
=
metaMem
.
getStr
(
offset
);
if
(
columnIndex
==
i
)
{
diskReadingRecord
.
name
=
name
;
diskReadingRecord
.
columnNumber
=
(
short
)
(
i
+
1
);
diskReadingRecord
.
tableId
=
tableId
;
columnIndex
++;
if
(
columnIndex
==
columnCount
)
{
readNextFileFromDisk
=
true
;
columnIndex
=
0
;
}
else
{
readNextFileFromDisk
=
false
;
}
return
true
;
}
offset
+=
ReadOnlyMemory
.
getStorageLength
(
name
);
}
}
}
while
(
hasNextFile
);
ff
.
findClose
(
findFileStruct
);
findFileStruct
=
0
;
hasNextFile
=
true
;
foundMetadataFile
=
false
;
return
false
;
}
private
static
class
DiskReadingRecord
implements
Record
{
public
CharSequence
name
=
null
;
public
short
columnNumber
=
0
;
public
int
tableId
=
0
;
@Override
public
short
getShort
(
int
col
)
{
return
columnNumber
;
}
@Override
public
int
getInt
(
int
col
)
{
return
tableId
;
}
@Override
public
CharSequence
getStr
(
int
col
)
{
return
name
;
}
@Override
public
CharSequence
getStrB
(
int
col
)
{
return
name
;
}
@Override
public
int
getStrLen
(
int
col
)
{
return
getStr
(
col
).
length
();
}
}
}
static
{
final
GenericRecordMetadata
metadata
=
new
GenericRecordMetadata
();
metadata
.
add
(
new
TableColumnMetadata
(
"attrelid"
,
ColumnType
.
INT
));
metadata
.
add
(
new
TableColumnMetadata
(
"attname"
,
ColumnType
.
STRING
));
metadata
.
add
(
new
TableColumnMetadata
(
"attnum"
,
ColumnType
.
SHORT
));
METADATA
=
metadata
;
}
}
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/IndexCatalogueCursor.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.catalogue
;
import
io.questdb.cairo.ColumnType
;
import
io.questdb.cairo.GenericRecordMetadata
;
import
io.questdb.cairo.TableColumnMetadata
;
import
io.questdb.cairo.sql.NoRandomAccessRecordCursor
;
import
io.questdb.cairo.sql.Record
;
import
io.questdb.cairo.sql.RecordMetadata
;
class
IndexCatalogueCursor
implements
NoRandomAccessRecordCursor
{
static
final
RecordMetadata
METADATA
;
private
static
final
IndexCatalogueRecord
record
=
new
IndexCatalogueRecord
();
@Override
public
void
close
()
{
}
@Override
public
Record
getRecord
()
{
return
record
;
}
@Override
public
boolean
hasNext
()
{
return
false
;
}
@Override
public
void
toTop
()
{
}
@Override
public
long
size
()
{
return
0
;
}
private
static
class
IndexCatalogueRecord
implements
Record
{
}
static
{
final
GenericRecordMetadata
metadata
=
new
GenericRecordMetadata
();
metadata
.
add
(
new
TableColumnMetadata
(
"indkey"
,
ColumnType
.
INT
));
metadata
.
add
(
new
TableColumnMetadata
(
"indrelid"
,
ColumnType
.
INT
));
metadata
.
add
(
new
TableColumnMetadata
(
"indexrelid"
,
ColumnType
.
INT
));
metadata
.
add
(
new
TableColumnMetadata
(
"indisprimary"
,
ColumnType
.
BOOLEAN
));
METADATA
=
metadata
;
}
}
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/IndexCatalogueFunctionFactory.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.catalogue
;
import
io.questdb.cairo.CairoConfiguration
;
import
io.questdb.cairo.sql.Function
;
import
io.questdb.griffin.FunctionFactory
;
import
io.questdb.griffin.engine.functions.CursorFunction
;
import
io.questdb.griffin.engine.functions.GenericRecordCursorFactory
;
import
io.questdb.std.ObjList
;
public
class
IndexCatalogueFunctionFactory
implements
FunctionFactory
{
@Override
public
String
getSignature
()
{
return
"pg_catalog.pg_index()"
;
}
public
Function
newInstance
(
ObjList
<
Function
>
args
,
int
position
,
CairoConfiguration
configuration
)
{
return
new
CursorFunction
(
position
,
new
GenericRecordCursorFactory
(
IndexCatalogueCursor
.
METADATA
,
new
IndexCatalogueCursor
(),
false
)
);
}
}
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/InformationSchemaCursor.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.catalogue
;
import
io.questdb.cairo.ColumnType
;
import
io.questdb.cairo.GenericRecordMetadata
;
import
io.questdb.cairo.TableColumnMetadata
;
import
io.questdb.cairo.sql.NoRandomAccessRecordCursor
;
import
io.questdb.cairo.sql.Record
;
import
io.questdb.cairo.sql.RecordMetadata
;
class
InformationSchemaCursor
implements
NoRandomAccessRecordCursor
{
static
final
RecordMetadata
METADATA
;
private
static
final
InformationSchemaRecord
record
=
new
InformationSchemaRecord
();
@Override
public
void
close
()
{
}
@Override
public
Record
getRecord
()
{
return
record
;
}
@Override
public
boolean
hasNext
()
{
return
false
;
}
@Override
public
void
toTop
()
{
}
@Override
public
long
size
()
{
return
0
;
}
private
static
class
InformationSchemaRecord
implements
Record
{
}
static
{
final
GenericRecordMetadata
metadata
=
new
GenericRecordMetadata
();
metadata
.
add
(
new
TableColumnMetadata
(
"x"
,
ColumnType
.
INT
));
metadata
.
add
(
new
TableColumnMetadata
(
"n"
,
ColumnType
.
INT
));
METADATA
=
metadata
;
}
}
core/src/main/java/io/questdb/griffin/engine/functions/catalogue/InformationSchemaFunctionFactory.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.catalogue
;
import
io.questdb.cairo.CairoConfiguration
;
import
io.questdb.cairo.sql.Function
;
import
io.questdb.griffin.FunctionFactory
;
import
io.questdb.griffin.engine.functions.CursorFunction
;
import
io.questdb.griffin.engine.functions.GenericRecordCursorFactory
;
import
io.questdb.std.ObjList
;
public
class
InformationSchemaFunctionFactory
implements
FunctionFactory
{
@Override
public
String
getSignature
()
{
return
"information_schema._pg_expandarray(I)"
;
}
public
Function
newInstance
(
ObjList
<
Function
>
args
,
int
position
,
CairoConfiguration
configuration
)
{
return
new
CursorFunction
(
position
,
new
GenericRecordCursorFactory
(
InformationSchemaCursor
.
METADATA
,
new
InformationSchemaCursor
(),
false
)
);
}
}
core/src/main/java/io/questdb/griffin/model/QueryModel.java
浏览文件 @
86062c80
...
...
@@ -56,11 +56,11 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
public
static
final
int
SET_OPERATION_INTERSECT
=
3
;
private
static
final
ObjList
<
String
>
modelTypeName
=
new
ObjList
<>();
private
final
ObjList
<
QueryColumn
>
bottomUpColumns
=
new
ObjList
<>();
private
final
CharSequenceHashSet
topDownNameSet
=
new
CharSequenceHashSet
();
private
final
LowerCaseCharSequenceHashSet
topDownNameSet
=
new
LowerCase
CharSequenceHashSet
();
private
final
ObjList
<
QueryColumn
>
topDownColumns
=
new
ObjList
<>();
private
final
CharSequenceObjHashMap
<
CharSequence
>
aliasToColumnNameMap
=
new
CharSequenceObjHashMap
<>();
private
final
CharSequenceObjHashMap
<
CharSequence
>
columnNameToAliasMap
=
new
CharSequenceObjHashMap
<>();
private
final
CharSequenceObjHashMap
<
QueryColumn
>
aliasToColumnMap
=
new
CharSequenceObjHashMap
<>();
private
final
LowerCaseCharSequenceObjHashMap
<
CharSequence
>
aliasToColumnNameMap
=
new
LowerCase
CharSequenceObjHashMap
<>();
private
final
LowerCaseCharSequenceObjHashMap
<
CharSequence
>
columnNameToAliasMap
=
new
LowerCase
CharSequenceObjHashMap
<>();
private
final
LowerCaseCharSequenceObjHashMap
<
QueryColumn
>
aliasToColumnMap
=
new
LowerCase
CharSequenceObjHashMap
<>();
private
final
ObjList
<
CharSequence
>
bottomUpColumnNames
=
new
ObjList
<>();
private
final
ObjList
<
QueryModel
>
joinModels
=
new
ObjList
<>();
private
final
ObjList
<
ExpressionNode
>
orderBy
=
new
ObjList
<>();
...
...
@@ -69,7 +69,7 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
private
final
IntHashSet
dependencies
=
new
IntHashSet
();
private
final
IntList
orderedJoinModels1
=
new
IntList
();
private
final
IntList
orderedJoinModels2
=
new
IntList
();
private
final
CharSequenceIntHashMap
aliasIndexes
=
new
CharSequenceIntHashMap
();
private
final
LowerCaseCharSequenceIntHashMap
aliasIndexes
=
new
LowerCase
CharSequenceIntHashMap
();
private
final
ObjList
<
ExpressionNode
>
expressionModels
=
new
ObjList
<>();
// collect frequency of column names from each join model
// and check if any of columns with frequency > 0 are selected
...
...
@@ -79,9 +79,9 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
private
final
ObjList
<
ExpressionNode
>
parsedWhere
=
new
ObjList
<>();
private
final
IntHashSet
parsedWhereConsts
=
new
IntHashSet
();
private
final
ArrayDeque
<
ExpressionNode
>
sqlNodeStack
=
new
ArrayDeque
<>();
private
final
CharSequenceIntHashMap
orderHash
=
new
CharSequenceIntHashMap
(
4
,
0.5
,
-
1
);
private
final
LowerCaseCharSequenceIntHashMap
orderHash
=
new
LowerCase
CharSequenceIntHashMap
(
4
,
0.5
,
-
1
);
private
final
ObjList
<
ExpressionNode
>
joinColumns
=
new
ObjList
<>(
4
);
private
final
CharSequenceObjHashMap
<
WithClauseModel
>
withClauses
=
new
CharSequenceObjHashMap
<>();
private
final
LowerCaseCharSequenceObjHashMap
<
WithClauseModel
>
withClauses
=
new
LowerCase
CharSequenceObjHashMap
<>();
private
final
ObjList
<
ExpressionNode
>
sampleByFill
=
new
ObjList
<>();
private
final
ObjList
<
ExpressionNode
>
latestBy
=
new
ObjList
<>();
private
final
ObjList
<
ExpressionNode
>
orderByAdvice
=
new
ObjList
<>();
...
...
@@ -182,7 +182,7 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
withClauses
.
put
(
name
,
model
);
}
public
void
addWithClauses
(
CharSequenceObjHashMap
<
WithClauseModel
>
parentWithClauses
)
{
public
void
addWithClauses
(
LowerCase
CharSequenceObjHashMap
<
WithClauseModel
>
parentWithClauses
)
{
withClauses
.
putAll
(
parentWithClauses
);
}
...
...
@@ -288,11 +288,11 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
return
-
1
;
}
public
CharSequenceObjHashMap
<
QueryColumn
>
getAliasToColumnMap
()
{
public
LowerCase
CharSequenceObjHashMap
<
QueryColumn
>
getAliasToColumnMap
()
{
return
aliasToColumnMap
;
}
public
CharSequenceObjHashMap
<
CharSequence
>
getAliasToColumnNameMap
()
{
public
LowerCase
CharSequenceObjHashMap
<
CharSequence
>
getAliasToColumnNameMap
()
{
return
aliasToColumnNameMap
;
}
...
...
@@ -304,7 +304,7 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
return
bottomUpColumns
;
}
public
CharSequenceObjHashMap
<
CharSequence
>
getColumnNameToAliasMap
()
{
public
LowerCase
CharSequenceObjHashMap
<
CharSequence
>
getColumnNameToAliasMap
()
{
return
columnNameToAliasMap
;
}
...
...
@@ -441,7 +441,7 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
return
orderByDirectionAdvice
;
}
public
CharSequenceIntHashMap
getOrderHash
()
{
public
LowerCase
CharSequenceIntHashMap
getOrderHash
()
{
return
orderHash
;
}
...
...
@@ -550,7 +550,7 @@ public class QueryModel implements Mutable, ExecutionModel, AliasTranslator, Sin
return
withClauses
.
get
(
name
);
}
public
CharSequenceObjHashMap
<
WithClauseModel
>
getWithClauses
()
{
public
LowerCase
CharSequenceObjHashMap
<
WithClauseModel
>
getWithClauses
()
{
return
withClauses
;
}
...
...
core/src/main/java/io/questdb/std/AbstractLowerCaseCharSequenceHashSet.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.std
;
import
java.util.Arrays
;
public
abstract
class
AbstractLowerCaseCharSequenceHashSet
implements
Mutable
{
protected
static
final
CharSequence
noEntryKey
=
null
;
protected
static
final
int
MIN_INITIAL_CAPACITY
=
16
;
protected
final
double
loadFactor
;
protected
int
mask
;
protected
int
free
;
protected
int
capacity
;
// exposed for testing only
protected
CharSequence
[]
keys
;
public
AbstractLowerCaseCharSequenceHashSet
(
int
initialCapacity
,
double
loadFactor
)
{
if
(
loadFactor
<=
0
d
||
loadFactor
>=
1
d
)
{
throw
new
IllegalArgumentException
(
"0 < loadFactor < 1"
);
}
free
=
this
.
capacity
=
Math
.
max
(
initialCapacity
,
MIN_INITIAL_CAPACITY
);
this
.
loadFactor
=
loadFactor
;
keys
=
new
CharSequence
[
Numbers
.
ceilPow2
((
int
)
(
this
.
capacity
/
loadFactor
))];
mask
=
keys
.
length
-
1
;
}
@Override
public
void
clear
()
{
Arrays
.
fill
(
keys
,
noEntryKey
);
free
=
this
.
capacity
;
}
public
boolean
excludes
(
CharSequence
key
)
{
return
keyIndex
(
key
)
>
-
1
;
}
public
boolean
excludes
(
CharSequence
key
,
int
lo
,
int
hi
)
{
return
keyIndex
(
key
,
lo
,
hi
)
>
-
1
;
}
public
int
keyIndex
(
CharSequence
key
)
{
int
index
=
Chars
.
lowerCaseHashCode
(
key
)
&
mask
;
if
(
keys
[
index
]
==
noEntryKey
)
{
return
index
;
}
if
(
Chars
.
equalsLowerCase
(
key
,
keys
[
index
]))
{
return
-
index
-
1
;
}
return
probe
(
key
,
index
);
}
public
int
keyIndex
(
CharSequence
key
,
int
lo
,
int
hi
)
{
int
index
=
Chars
.
lowerCaseHashCode
(
key
,
lo
,
hi
)
&
mask
;
if
(
keys
[
index
]
==
noEntryKey
)
{
return
index
;
}
CharSequence
cs
=
keys
[
index
];
if
(
Chars
.
equalsLowerCase
(
key
,
lo
,
hi
,
cs
,
0
,
cs
.
length
()))
{
return
-
index
-
1
;
}
return
probe
(
key
,
lo
,
hi
,
index
);
}
public
int
remove
(
CharSequence
key
)
{
int
index
=
keyIndex
(
key
);
if
(
index
<
0
)
{
removeAt
(
index
);
return
-
index
-
1
;
}
return
-
1
;
}
public
void
removeAt
(
int
index
)
{
if
(
index
<
0
)
{
int
from
=
-
index
-
1
;
erase
(
from
);
free
++;
// after we have freed up a slot
// consider non-empty keys directly below
// they may have been a direct hit but because
// directly hit slot wasn't empty these keys would
// have moved.
//
// After slot if freed these keys require re-hash
from
=
(
from
+
1
)
&
mask
;
for
(
CharSequence
key
=
keys
[
from
];
key
!=
noEntryKey
;
from
=
(
from
+
1
)
&
mask
,
key
=
keys
[
from
]
)
{
int
idealHit
=
Chars
.
lowerCaseHashCode
(
key
)
&
mask
;
if
(
idealHit
!=
from
)
{
int
to
;
if
(
keys
[
idealHit
]
!=
noEntryKey
)
{
to
=
probe
(
key
,
idealHit
);
}
else
{
to
=
idealHit
;
}
if
(
to
>
-
1
)
{
move
(
from
,
to
);
}
}
}
}
}
public
int
size
()
{
return
capacity
-
free
;
}
/**
* Erases entry in array.
*
* @param index always positive, no arithmetic required.
*/
abstract
protected
void
erase
(
int
index
);
abstract
protected
void
move
(
int
from
,
int
to
);
private
int
probe
(
CharSequence
key
,
int
index
)
{
do
{
index
=
(
index
+
1
)
&
mask
;
if
(
keys
[
index
]
==
noEntryKey
)
{
return
index
;
}
if
(
Chars
.
equalsLowerCase
(
key
,
keys
[
index
]))
{
return
-
index
-
1
;
}
}
while
(
true
);
}
private
int
probe
(
CharSequence
key
,
int
lo
,
int
hi
,
int
index
)
{
do
{
index
=
(
index
+
1
)
&
mask
;
if
(
keys
[
index
]
==
noEntryKey
)
{
return
index
;
}
CharSequence
cs
=
keys
[
index
];
if
(
Chars
.
equalsLowerCase
(
key
,
lo
,
hi
,
cs
,
0
,
cs
.
length
()))
{
return
-
index
-
1
;
}
}
while
(
true
);
}
}
core/src/main/java/io/questdb/std/Chars.java
浏览文件 @
86062c80
...
...
@@ -230,6 +230,39 @@ public final class Chars {
return
l
!=
null
&&
equalsIgnoreCase
(
l
,
r
);
}
public
static
boolean
equalsLowerCase
(
CharSequence
l
,
int
lLo
,
int
lHi
,
CharSequence
r
,
int
rLo
,
int
rHi
)
{
if
(
l
==
r
)
{
return
true
;
}
int
ll
=
lHi
-
lLo
;
if
(
ll
!=
rHi
-
rLo
)
{
return
false
;
}
for
(
int
i
=
0
;
i
<
ll
;
i
++)
{
if
(
Character
.
toLowerCase
(
l
.
charAt
(
i
+
lLo
))
!=
Character
.
toLowerCase
(
r
.
charAt
(
i
+
rLo
)))
{
return
false
;
}
}
return
true
;
}
public
static
boolean
equalsLowerCase
(
@NotNull
CharSequence
l
,
CharSequence
r
)
{
int
ll
;
if
((
ll
=
l
.
length
())
!=
r
.
length
())
{
return
false
;
}
for
(
int
i
=
0
;
i
<
ll
;
i
++)
{
if
(
Character
.
toLowerCase
(
l
.
charAt
(
i
))
!=
Character
.
toLowerCase
(
r
.
charAt
(
i
)))
{
return
false
;
}
}
return
true
;
}
public
static
boolean
equalsLowerCaseAscii
(
CharSequence
l
,
int
lLo
,
int
lHi
,
CharSequence
r
,
int
rLo
,
int
rHi
)
{
if
(
l
==
r
)
{
return
true
;
...
...
@@ -241,7 +274,7 @@ public final class Chars {
}
for
(
int
i
=
0
;
i
<
ll
;
i
++)
{
if
(
toLowerCaseAscii
(
l
.
charAt
(
i
+
lLo
))
!=
r
.
charAt
(
i
+
rLo
))
{
if
(
toLowerCaseAscii
(
l
.
charAt
(
i
+
lLo
))
!=
toLowerCaseAscii
(
r
.
charAt
(
i
+
rLo
)
))
{
return
false
;
}
}
...
...
@@ -255,7 +288,7 @@ public final class Chars {
}
for
(
int
i
=
0
;
i
<
ll
;
i
++)
{
if
(
toLowerCaseAscii
(
l
.
charAt
(
i
))
!=
r
.
charAt
(
i
))
{
if
(
toLowerCaseAscii
(
l
.
charAt
(
i
))
!=
toLowerCaseAscii
(
r
.
charAt
(
i
)
))
{
return
false
;
}
}
...
...
@@ -389,6 +422,31 @@ public final class Chars {
return
h
;
}
public
static
int
lowerCaseHashCode
(
CharSequence
value
,
int
lo
,
int
hi
)
{
if
(
hi
==
lo
)
{
return
0
;
}
int
h
=
0
;
for
(
int
p
=
lo
;
p
<
hi
;
p
++)
{
h
=
31
*
h
+
Character
.
toLowerCase
(
value
.
charAt
(
p
));
}
return
h
;
}
public
static
int
lowerCaseHashCode
(
CharSequence
value
)
{
int
len
=
value
.
length
();
if
(
len
==
0
)
{
return
0
;
}
int
h
=
0
;
for
(
int
p
=
0
;
p
<
len
;
p
++)
{
h
=
31
*
h
+
Character
.
toLowerCase
(
value
.
charAt
(
p
));
}
return
h
;
}
public
static
boolean
noMatch
(
CharSequence
l
,
int
llo
,
int
lhi
,
CharSequence
r
,
int
rlo
,
int
rhi
)
{
int
lp
=
llo
;
int
rp
=
rlo
;
...
...
@@ -498,8 +556,6 @@ public final class Chars {
b
.
put
(
toLowerCaseAscii
(
value
.
charAt
(
i
)));
}
return
b
.
toString
();
}
public
static
char
toLowerCaseAscii
(
char
character
)
{
...
...
@@ -765,4 +821,15 @@ public final class Chars {
sink
.
put
((
char
)
(
b1
<<
6
^
b2
^
3968
));
return
2
;
}
public
static
String
toLowerCase
(
CharSequence
str
)
{
final
CharSink
sink
=
Misc
.
getThreadLocalBuilder
();
if
(
str
!=
null
)
{
final
int
len
=
str
.
length
();
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
sink
.
put
(
Character
.
toLowerCase
(
str
.
charAt
(
i
)));
}
}
return
sink
.
toString
();
}
}
core/src/main/java/io/questdb/std/LowerCaseCharSequenceHashSet.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.std
;
public
class
LowerCaseCharSequenceHashSet
extends
AbstractLowerCaseCharSequenceHashSet
{
private
static
final
int
MIN_INITIAL_CAPACITY
=
16
;
public
LowerCaseCharSequenceHashSet
()
{
this
(
MIN_INITIAL_CAPACITY
);
}
private
LowerCaseCharSequenceHashSet
(
int
initialCapacity
)
{
this
(
initialCapacity
,
0.4
);
}
private
LowerCaseCharSequenceHashSet
(
int
initialCapacity
,
double
loadFactor
)
{
super
(
initialCapacity
,
loadFactor
);
clear
();
}
/**
* Adds key to hash set preserving key uniqueness.
*
* @param key immutable sequence of characters.
* @return false if key is already in the set and true otherwise.
*/
public
boolean
add
(
CharSequence
key
)
{
int
index
=
keyIndex
(
key
);
if
(
index
<
0
)
{
return
false
;
}
addAt
(
index
,
key
);
return
true
;
}
public
void
addAt
(
int
index
,
CharSequence
key
)
{
keys
[
index
]
=
key
;
if
(--
free
<
1
)
{
rehash
();
}
}
public
boolean
contains
(
CharSequence
key
)
{
return
keyIndex
(
key
)
<
0
;
}
public
CharSequence
keyAt
(
int
index
)
{
return
keys
[-
index
-
1
];
}
@Override
protected
void
erase
(
int
index
)
{
keys
[
index
]
=
noEntryKey
;
}
@Override
protected
void
move
(
int
from
,
int
to
)
{
keys
[
to
]
=
keys
[
from
];
erase
(
from
);
}
private
void
rehash
()
{
int
newCapacity
=
capacity
*
2
;
final
int
size
=
size
();
free
=
capacity
=
newCapacity
;
int
len
=
Numbers
.
ceilPow2
((
int
)
(
newCapacity
/
loadFactor
));
CharSequence
[]
newKeys
=
new
CharSequence
[
len
];
CharSequence
[]
oldKeys
=
keys
;
mask
=
len
-
1
;
this
.
keys
=
newKeys
;
free
-=
size
;
for
(
int
i
=
0
,
n
=
oldKeys
.
length
;
i
<
n
;
i
++)
{
CharSequence
key
=
oldKeys
[
i
];
if
(
key
!=
null
)
{
keys
[
keyIndex
(
key
)]
=
key
;
}
}
}
}
\ No newline at end of file
core/src/main/java/io/questdb/std/LowerCaseCharSequenceIntHashMap.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.std
;
import
java.util.Arrays
;
public
class
LowerCaseCharSequenceIntHashMap
extends
AbstractLowerCaseCharSequenceHashSet
{
private
static
final
int
NO_ENTRY_VALUE
=
-
1
;
private
final
int
noEntryValue
;
protected
int
[]
values
;
private
final
ObjList
<
CharSequence
>
list
;
public
LowerCaseCharSequenceIntHashMap
()
{
this
(
8
);
}
public
LowerCaseCharSequenceIntHashMap
(
int
initialCapacity
)
{
this
(
initialCapacity
,
0.5
,
NO_ENTRY_VALUE
);
}
public
LowerCaseCharSequenceIntHashMap
(
int
initialCapacity
,
double
loadFactor
,
int
noEntryValue
)
{
super
(
initialCapacity
,
loadFactor
);
this
.
noEntryValue
=
noEntryValue
;
this
.
list
=
new
ObjList
<>(
capacity
);
values
=
new
int
[
keys
.
length
];
clear
();
}
public
void
clear
()
{
super
.
clear
();
list
.
clear
();
Arrays
.
fill
(
values
,
noEntryValue
);
}
@Override
protected
void
erase
(
int
index
)
{
keys
[
index
]
=
noEntryKey
;
values
[
index
]
=
noEntryValue
;
}
public
void
removeAt
(
int
index
)
{
if
(
index
<
0
)
{
int
index1
=
-
index
-
1
;
CharSequence
key
=
keys
[
index1
];
super
.
removeAt
(
index
);
list
.
remove
(
key
);
}
}
public
int
valueAt
(
int
index
)
{
return
index
<
0
?
values
[-
index
-
1
]
:
noEntryValue
;
}
public
boolean
contains
(
CharSequence
key
)
{
return
keyIndex
(
key
)
<
0
;
}
public
int
get
(
CharSequence
key
)
{
return
valueAt
(
keyIndex
(
key
));
}
public
boolean
put
(
CharSequence
key
,
int
value
)
{
return
putAt
(
keyIndex
(
key
),
key
,
value
);
}
public
boolean
putAt
(
int
index
,
CharSequence
key
,
int
value
)
{
if
(
index
<
0
)
{
values
[-
index
-
1
]
=
value
;
return
false
;
}
putAt0
(
index
,
key
,
value
);
list
.
add
(
key
);
return
true
;
}
public
void
putIfAbsent
(
CharSequence
key
,
int
value
)
{
int
index
=
keyIndex
(
key
);
if
(
index
>
-
1
)
{
putAt0
(
index
,
key
,
value
);
}
}
@Override
protected
void
move
(
int
from
,
int
to
)
{
keys
[
to
]
=
keys
[
from
];
values
[
to
]
=
values
[
from
];
erase
(
from
);
}
protected
void
putAt0
(
int
index
,
CharSequence
key
,
int
value
)
{
keys
[
index
]
=
key
;
values
[
index
]
=
value
;
if
(--
free
==
0
)
{
rehash
();
}
}
private
void
rehash
()
{
int
size
=
size
();
int
newCapacity
=
capacity
*
2
;
free
=
capacity
=
newCapacity
;
int
len
=
Numbers
.
ceilPow2
((
int
)
(
newCapacity
/
loadFactor
));
int
[]
oldValues
=
values
;
CharSequence
[]
oldKeys
=
keys
;
this
.
keys
=
new
CharSequence
[
len
];
this
.
values
=
new
int
[
len
];
Arrays
.
fill
(
keys
,
null
);
mask
=
len
-
1
;
free
-=
size
;
for
(
int
i
=
oldKeys
.
length
;
i
--
>
0
;
)
{
CharSequence
key
=
oldKeys
[
i
];
if
(
key
!=
null
)
{
final
int
index
=
keyIndex
(
key
);
keys
[
index
]
=
key
;
values
[
index
]
=
oldValues
[
i
];
}
}
}
public
ObjList
<
CharSequence
>
keys
()
{
return
list
;
}
}
\ No newline at end of file
core/src/main/java/io/questdb/std/LowerCaseCharSequenceObjHashMap.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.std
;
import
java.util.Arrays
;
public
class
LowerCaseCharSequenceObjHashMap
<
T
>
extends
AbstractLowerCaseCharSequenceHashSet
{
private
final
ObjList
<
CharSequence
>
list
;
private
T
[]
values
;
public
LowerCaseCharSequenceObjHashMap
()
{
this
(
8
);
}
public
LowerCaseCharSequenceObjHashMap
(
int
initialCapacity
)
{
this
(
initialCapacity
,
0.5
);
}
@SuppressWarnings
(
"unchecked"
)
public
LowerCaseCharSequenceObjHashMap
(
int
initialCapacity
,
double
loadFactor
)
{
super
(
initialCapacity
,
loadFactor
);
values
=
(
T
[])
new
Object
[
keys
.
length
];
this
.
list
=
new
ObjList
<>(
capacity
);
clear
();
}
public
final
void
clear
()
{
super
.
clear
();
list
.
clear
();
Arrays
.
fill
(
values
,
null
);
}
public
ObjList
<
CharSequence
>
keys
()
{
return
list
;
}
@Override
protected
void
erase
(
int
index
)
{
keys
[
index
]
=
noEntryKey
;
values
[
index
]
=
null
;
}
@Override
public
void
removeAt
(
int
index
)
{
if
(
index
<
0
)
{
CharSequence
key
=
keys
[-
index
-
1
];
super
.
removeAt
(
index
);
list
.
remove
(
key
);
}
}
public
boolean
contains
(
CharSequence
key
)
{
return
keyIndex
(
key
)
<
0
;
}
public
T
get
(
CharSequence
key
)
{
return
valueAt
(
keyIndex
(
key
));
}
@Override
protected
void
move
(
int
from
,
int
to
)
{
keys
[
to
]
=
keys
[
from
];
values
[
to
]
=
values
[
from
];
erase
(
from
);
}
public
boolean
put
(
CharSequence
key
,
T
value
)
{
return
putAt
(
keyIndex
(
key
),
key
,
value
);
}
public
boolean
putAt
(
int
index
,
CharSequence
key
,
T
value
)
{
if
(
index
<
0
)
{
values
[-
index
-
1
]
=
value
;
return
false
;
}
putAt0
(
index
,
key
,
value
);
list
.
add
(
key
);
return
true
;
}
public
void
putIfAbsent
(
CharSequence
key
,
T
value
)
{
int
index
=
keyIndex
(
key
);
if
(
index
>
-
1
)
{
putAt0
(
index
,
key
,
value
);
}
}
public
T
valueAt
(
int
index
)
{
return
index
<
0
?
valueAtQuick
(
index
)
:
null
;
}
public
T
valueAtQuick
(
int
index
)
{
return
values
[-
index
-
1
];
}
private
void
putAt0
(
int
index
,
CharSequence
key
,
T
value
)
{
keys
[
index
]
=
key
;
values
[
index
]
=
value
;
if
(--
free
==
0
)
{
rehash
();
}
}
@SuppressWarnings
(
"unchecked"
)
private
void
rehash
()
{
int
size
=
size
();
int
newCapacity
=
capacity
*
2
;
free
=
capacity
=
newCapacity
;
int
arrayCapacity
=
Numbers
.
ceilPow2
((
int
)
(
newCapacity
/
loadFactor
));
T
[]
oldValues
=
values
;
CharSequence
[]
oldKeys
=
keys
;
this
.
keys
=
new
CharSequence
[
arrayCapacity
];
this
.
values
=
(
T
[])
new
Object
[
arrayCapacity
];
Arrays
.
fill
(
keys
,
null
);
mask
=
arrayCapacity
-
1
;
free
-=
size
;
for
(
int
i
=
oldKeys
.
length
;
i
--
>
0
;
)
{
CharSequence
key
=
oldKeys
[
i
];
if
(
key
!=
null
)
{
final
int
index
=
keyIndex
(
key
);
keys
[
index
]
=
key
;
values
[
index
]
=
oldValues
[
i
];
}
}
}
public
void
putAll
(
LowerCaseCharSequenceObjHashMap
<
T
>
other
)
{
CharSequence
[]
otherKeys
=
other
.
keys
;
T
[]
otherValues
=
other
.
values
;
for
(
int
i
=
0
,
n
=
otherKeys
.
length
;
i
<
n
;
i
++)
{
if
(
otherKeys
[
i
]
!=
noEntryKey
)
{
put
(
otherKeys
[
i
],
otherValues
[
i
]);
}
}
}
}
\ No newline at end of file
core/src/main/java/module-info.java
浏览文件 @
86062c80
...
...
@@ -455,7 +455,10 @@ open module io.questdb {
io
.
questdb
.
griffin
.
engine
.
functions
.
conditional
.
CaseFunctionFactory
,
io
.
questdb
.
griffin
.
engine
.
functions
.
conditional
.
SwitchFunctionFactory
,
// PostgeSQL catalogue functions
io
.
questdb
.
griffin
.
engine
.
functions
.
catalogue
.
AttributeCatalogueFunctionFactory
,
io
.
questdb
.
griffin
.
engine
.
functions
.
catalogue
.
ClassCatalogueFunctionFactory
,
io
.
questdb
.
griffin
.
engine
.
functions
.
catalogue
.
IndexCatalogueFunctionFactory
,
io
.
questdb
.
griffin
.
engine
.
functions
.
catalogue
.
InformationSchemaFunctionFactory
,
io
.
questdb
.
griffin
.
engine
.
functions
.
catalogue
.
PrefixedNamespaceCatalogueFunctionFactory
,
io
.
questdb
.
griffin
.
engine
.
functions
.
catalogue
.
NamespaceCatalogueFunctionFactory
,
io
.
questdb
.
griffin
.
engine
.
functions
.
catalogue
.
IsTableVisibleCatalogueFunctionFactory
,
...
...
core/src/main/resources/META-INF/services/io.questdb.griffin.FunctionFactory
浏览文件 @
86062c80
...
...
@@ -22,6 +22,30 @@
#
################################################################################
################################################################################
# ___ _ ____ ____
# / _ \ _ _ ___ ___| |_| _ \| __ )
# | | | | | | |/ _ \/ __| __| | | | _ \
# | |_| | |_| | __/\__ \ |_| |_| | |_) |
# \__\_\\__,_|\___||___/\__|____/|____/
#
# 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.
#
################################################################################
################################################################################
# ___ _ ____ ____
...
...
@@ -463,8 +487,11 @@ io.questdb.griffin.engine.functions.math.RoundHalfEvenDoubleFunctionFactory
io.questdb.griffin.engine.functions.conditional.CaseFunctionFactory
io.questdb.griffin.engine.functions.conditional.SwitchFunctionFactory
# PostgeSQL catalogue functions
# PostgreSQL catalogue functions
io.questdb.griffin.engine.functions.catalogue.AttributeCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.ClassCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.IndexCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.InformationSchemaFunctionFactory
io.questdb.griffin.engine.functions.catalogue.PrefixedNamespaceCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.IsTableVisibleCatalogueFunctionFactory
io.questdb.griffin.engine.functions.catalogue.UserByIdCatalogueFunctionFactory
...
...
core/src/test/java/io/questdb/cairo/GenericRecordMetadataTest.java
浏览文件 @
86062c80
...
...
@@ -78,6 +78,31 @@ public class GenericRecordMetadataTest {
TestUtils
.
assertEquals
(
expected
,
sink
);
}
@Test
public
void
testDuplicateColumn2
()
{
final
String
expected
=
"{\"columnCount\":2,\"columns\":[{\"index\":0,\"name\":\"abc\",\"type\":\"INT\"},{\"index\":1,\"name\":\"cde\",\"type\":\"INT\"}],\"timestampIndex\":-1}"
;
GenericRecordMetadata
metadata
=
new
GenericRecordMetadata
();
metadata
.
add
(
new
TableColumnMetadata
(
"abc"
,
ColumnType
.
INT
));
metadata
.
add
(
new
TableColumnMetadata
(
"cde"
,
ColumnType
.
INT
));
sink
.
clear
();
metadata
.
toJson
(
sink
);
TestUtils
.
assertEquals
(
expected
,
sink
);
try
{
metadata
.
add
(
new
TableColumnMetadata
(
"ABC"
,
ColumnType
.
FLOAT
));
Assert
.
fail
();
}
catch
(
CairoException
e
)
{
TestUtils
.
assertContains
(
e
.
getMessage
(),
"Duplicate column"
);
}
sink
.
clear
();
metadata
.
toJson
(
sink
);
TestUtils
.
assertEquals
(
expected
,
sink
);
}
@Test
public
void
testReuse
()
{
String
expected1
=
"{\"columnCount\":3,\"columns\":[{\"index\":0,\"name\":\"abc\",\"type\":\"INT\"},{\"index\":1,\"name\":\"cde\",\"type\":\"INT\"},{\"index\":2,\"name\":\"timestamp\",\"type\":\"TIMESTAMP\"}],\"timestampIndex\":2}"
;
...
...
core/src/test/java/io/questdb/griffin/engine/functions/catalogue/AttributeCatalogueFunctionFactoryTest.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.catalogue
;
import
io.questdb.griffin.AbstractGriffinTest
;
import
org.junit.Test
;
public
class
AttributeCatalogueFunctionFactoryTest
extends
AbstractGriffinTest
{
@Test
public
void
testPgAttributeFunc
()
throws
Exception
{
assertQuery
(
"attrelid\tattname\tattnum\n"
+
"1\ta\t1\n"
,
"pg_catalog.pg_attribute;"
,
"create table x(a int)"
,
null
,
false
,
false
);
}
@Test
public
void
testPgAttributeFuncNoTables
()
throws
Exception
{
assertQuery
(
"attrelid\tattname\tattnum\n"
,
"pg_catalog.pg_attribute;"
,
null
,
null
,
false
,
false
);
}
@Test
public
void
testPgAttributeFuncWith2Tables
()
throws
Exception
{
assertQuery
(
"attrelid\tattname\tattnum\n"
+
"1\ta\t1\n"
,
"pg_catalog.pg_attribute order by 1;"
,
"create table x(a int)"
,
null
,
"create table y(a double, b string)"
,
"attrelid\tattname\tattnum\n"
+
"1\ta\t1\n"
+
"2\ta\t1\n"
+
"2\tb\t2\n"
,
true
,
false
,
false
);
}
@Test
public
void
testPgAttributeFuncWith2TablesLimit1
()
throws
Exception
{
assertQuery
(
"attrelid\tattname\tattnum\n"
+
"1\ta\t1\n"
,
"pg_catalog.pg_attribute order by 1 limit 1;"
,
"create table x(a int)"
,
null
,
"create table y(a double, b string)"
,
"attrelid\tattname\tattnum\n"
+
"1\ta\t1\n"
,
true
,
false
,
true
);
}
@Test
public
void
testKafkaMetadataQuery
()
throws
Exception
{
String
query
=
"\n"
+
"SELECT\n"
+
" result.TABLE_CAT, \n"
+
" result.TABLE_SCHEM, \n"
+
" result.TABLE_NAME, \n"
+
" result.COLUMN_NAME, \n"
+
" result.KEY_SEQ, \n"
+
" result.PK_NAME,\n"
+
" result.KEYS,\n"
+
" result.A_ATTNUM,\n"
+
" RAW \n"
+
"FROM\n"
+
" (SELECT \n"
+
" NULL AS TABLE_CAT, \n"
+
" n.nspname AS TABLE_SCHEM, \n"
+
" ct.relname AS TABLE_NAME, \n"
+
" a.attname AS COLUMN_NAME, \n"
+
" (information_schema._pg_expandarray(i.indkey)).n AS KEY_SEQ, \n"
+
" ci.relname AS PK_NAME, \n"
+
" information_schema._pg_expandarray(i.indkey) AS KEYS, \n"
+
" a.attnum AS A_ATTNUM,\n"
+
" i.indkey AS RAW \n"
+
" FROM pg_catalog.pg_class ct\n"
+
" JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) \n"
+
" JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) \n"
+
" JOIN pg_catalog.pg_index i ON ( a.attrelid = i.indrelid) \n"
+
" JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) \n"
+
" WHERE \n"
+
" true \n"
+
" AND ct.relname = E'po_items' \n"
+
" AND i.indisprimary \n"
+
" ) result; \n"
;
assertQuery
(
"TABLE_CAT\tTABLE_SCHEM\tTABLE_NAME\tCOLUMN_NAME\tKEY_SEQ\tPK_NAME\tKEYS\tA_ATTNUM\tRAW\n"
,
query
,
"create table x(a int)"
,
null
,
false
,
false
);
}
@Test
public
void
testKafkaMetadataQueryCaseInsensitivity1
()
throws
Exception
{
String
query
=
"SELECT\n"
+
" result.TABLE_CAT, \n"
+
" result.TABLE_SCHEM, \n"
+
" result.TABLE_NAME, \n"
+
" result.COLUMN_NAME, \n"
+
" result.KEY_SEQ, \n"
+
" result.PK_NAME,\n"
+
" -- result.KEYS,\n"
+
" result.A_ATTNUM,\n"
+
" RAW \n"
+
"FROM\n"
+
" (SELECT \n"
+
" NULL AS TABLE_CAT, \n"
+
" n.nspname AS TABLE_SCHEM, \n"
+
" ct.relname AS TABLE_NAME, \n"
+
" a.attname AS COLUMN_NAME, \n"
+
" (information_schema._pg_expandarray(i.indkey)).n AS KEY_SEQ, \n"
+
" ci.relname AS PK_NAME, \n"
+
" -- information_schema._pg_expandarray(i.indkey) AS KEYS, \n"
+
" a.attnum AS A_ATTNUM,\n"
+
" i.indkey AS RAW \n"
+
" FROM pg_catalog.pg_class ct\n"
+
" JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) \n"
+
" JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) \n"
+
" JOIN pg_catalog.pg_index i ON ( a.attrelid = i.indrelid) \n"
+
" JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) \n"
+
" WHERE \n"
+
" true \n"
+
" AND ct.relname = E'po_items' \n"
+
" AND i.indisprimary \n"
+
" ) result \n"
+
"--WHERE A_ATTNUM = (result.KEYS).x \n"
+
"ORDER BY result.table_name, result.PK_NAME, result.KEY_SEQ;"
;
assertQuery
(
"TABLE_CAT\tTABLE_SCHEM\tTABLE_NAME\tCOLUMN_NAME\tKEY_SEQ\tPK_NAME\tA_ATTNUM\tRAW\n"
,
query
,
"create table x(a int)"
,
null
,
true
,
false
);
}
@Test
public
void
testKafkaMetadataQueryCaseInsensitivity2
()
throws
Exception
{
String
query
=
"SELECT\n"
+
" result.TABLE_CAT, \n"
+
" result.TABLE_SCHEM, \n"
+
" result.TABLE_NAME, \n"
+
" result.COLUMN_NAME, \n"
+
" result.KEY_SEQ, \n"
+
" result.PK_NAME,\n"
+
" -- result.KEYS,\n"
+
" result.A_ATTNUM,\n"
+
" RAW \n"
+
"FROM\n"
+
" (SELECT \n"
+
" NULL AS TABLE_CAT, \n"
+
" n.nspname AS TABLE_SCHEM, \n"
+
" ct.relname AS TABLE_NAME, \n"
+
" a.attname AS COLUMN_NAME, \n"
+
" (information_schema._pg_expandarray(i.indkey)).n AS KEY_SEQ, \n"
+
" ci.relname AS PK_NAME, \n"
+
" -- information_schema._pg_expandarray(i.indkey) AS KEYS, \n"
+
" a.attnum AS A_ATTNUM,\n"
+
" i.indkey AS RAW \n"
+
" FROM pg_catalog.pg_class ct\n"
+
" JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) \n"
+
" JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) \n"
+
" JOIN pg_catalog.pg_index i ON ( a.attrelid = i.indrelid) \n"
+
" JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) \n"
+
" WHERE \n"
+
" true \n"
+
" AND ct.relname = E'po_items' \n"
+
" AND i.indisprimary \n"
+
" ) result \n"
+
"--WHERE A_ATTNUM = (result.KEYS).x \n"
+
"ORDER BY result.TABLE_NAME, result.pk_name, result.KEY_SEQ;"
;
assertQuery
(
"TABLE_CAT\tTABLE_SCHEM\tTABLE_NAME\tCOLUMN_NAME\tKEY_SEQ\tPK_NAME\tA_ATTNUM\tRAW\n"
,
query
,
"create table x(a int)"
,
null
,
true
,
false
);
}
}
\ No newline at end of file
core/src/test/java/io/questdb/griffin/engine/functions/catalogue/IndexCatalogueFunctionFactoryTest.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.catalogue
;
import
io.questdb.griffin.AbstractGriffinTest
;
import
org.junit.Test
;
public
class
IndexCatalogueFunctionFactoryTest
extends
AbstractGriffinTest
{
@Test
public
void
testPgIndexFunc
()
throws
Exception
{
assertQuery
(
"indkey\tindrelid\tindexrelid\tindisprimary\n"
,
"pg_catalog.pg_index;"
,
"create table x(a int)"
,
null
,
false
,
false
,
true
);
}
}
\ No newline at end of file
core/src/test/java/io/questdb/griffin/engine/functions/catalogue/InformationSchemaFunctionFactoryTest.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.catalogue
;
import
io.questdb.griffin.AbstractGriffinTest
;
import
org.junit.Test
;
public
class
InformationSchemaFunctionFactoryTest
extends
AbstractGriffinTest
{
@Test
public
void
testInformationSchemaPivotFunc
()
throws
Exception
{
assertQuery
(
"x\tn\n"
,
"information_schema._pg_expandarray(5);"
,
"create table x(a int)"
,
null
,
false
,
false
,
true
);
}
}
\ No newline at end of file
core/src/test/java/io/questdb/std/LowerCaseCharSequenceHashSetTest.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.std
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
java.util.HashSet
;
public
class
LowerCaseCharSequenceHashSetTest
{
@Test
public
void
testSaturation
()
{
final
int
N
=
10_000
;
final
Rnd
rnd
=
new
Rnd
();
final
LowerCaseCharSequenceHashSet
lowerCaseSet
=
new
LowerCaseCharSequenceHashSet
();
final
HashSet
<
String
>
referenceSet
=
new
HashSet
<>();
for
(
int
i
=
0
;
i
<
N
;
i
++)
{
String
str
=
rnd
.
nextString
(
4
);
int
keyIndex
=
lowerCaseSet
.
keyIndex
(
str
,
0
,
str
.
length
());
if
(
lowerCaseSet
.
add
(
str
))
{
Assert
.
assertTrue
(
"at "
+
i
,
referenceSet
.
add
(
str
));
Assert
.
assertTrue
(
keyIndex
>
-
1
);
}
else
{
Assert
.
assertTrue
(
keyIndex
<
0
);
}
}
// verify
for
(
String
s
:
referenceSet
)
{
Assert
.
assertTrue
(
lowerCaseSet
.
contains
(
s
));
Assert
.
assertFalse
(
lowerCaseSet
.
excludes
(
s
));
Assert
.
assertFalse
(
lowerCaseSet
.
excludes
(
s
,
0
,
s
.
length
()));
int
keyIndex
=
lowerCaseSet
.
keyIndex
(
s
);
Assert
.
assertTrue
(
keyIndex
<
0
);
Assert
.
assertTrue
(
Chars
.
equals
(
s
,
lowerCaseSet
.
keyAt
(
keyIndex
)));
keyIndex
=
lowerCaseSet
.
keyIndex
(
s
,
0
,
s
.
length
());
Assert
.
assertTrue
(
Chars
.
equals
(
s
,
lowerCaseSet
.
keyAt
(
keyIndex
)));
}
for
(
int
i
=
0
,
n
=
lowerCaseSet
.
keys
.
length
;
i
<
n
;
i
++)
{
CharSequence
v
=
lowerCaseSet
.
keys
[
i
];
if
(
v
!=
null
)
{
Assert
.
assertTrue
(
referenceSet
.
contains
(
v
.
toString
()));
}
}
// remove every forth key
// make sure rnd generates the same keys again
rnd
.
reset
();
for
(
int
i
=
0
;
i
<
N
;
i
++)
{
String
s
=
rnd
.
nextString
(
4
);
if
(
i
%
4
==
0
)
{
lowerCaseSet
.
remove
(
s
);
referenceSet
.
remove
(
s
);
}
}
// verify
for
(
String
s
:
referenceSet
)
{
Assert
.
assertTrue
(
s
,
lowerCaseSet
.
contains
(
s
));
}
for
(
int
i
=
0
,
n
=
lowerCaseSet
.
keys
.
length
;
i
<
n
;
i
++)
{
CharSequence
v
=
lowerCaseSet
.
keys
[
i
];
if
(
v
!=
null
)
{
Assert
.
assertTrue
(
referenceSet
.
contains
(
v
.
toString
()));
}
}
}
}
\ No newline at end of file
core/src/test/java/io/questdb/std/LowerCaseCharSequenceIntHashMapTest.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.std
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
LowerCaseCharSequenceIntHashMapTest
{
@Test
public
void
testSaturation
()
{
final
int
N
=
10_000
;
final
Rnd
rnd
=
new
Rnd
();
final
LowerCaseCharSequenceIntHashMap
lowerCaseMap
=
new
LowerCaseCharSequenceIntHashMap
();
final
HashMap
<
String
,
Integer
>
referenceMap
=
new
HashMap
<>();
for
(
int
i
=
0
;
i
<
N
;
i
++)
{
String
str
=
rnd
.
nextString
(
4
);
int
value
=
rnd
.
nextInt
();
int
keyIndex
=
lowerCaseMap
.
keyIndex
(
str
,
0
,
str
.
length
());
if
(
lowerCaseMap
.
put
(
str
,
value
))
{
Assert
.
assertNull
(
"at "
+
i
,
referenceMap
.
put
(
str
,
value
));
Assert
.
assertTrue
(
keyIndex
>
-
1
);
}
else
{
Assert
.
assertTrue
(
keyIndex
<
0
);
// this should fail to put
lowerCaseMap
.
putIfAbsent
(
str
,
value
);
lowerCaseMap
.
putAt
(
keyIndex
,
str
,
referenceMap
.
get
(
str
));
}
}
// verify
for
(
Map
.
Entry
<
String
,
Integer
>
e
:
referenceMap
.
entrySet
())
{
Assert
.
assertTrue
(
lowerCaseMap
.
contains
(
e
.
getKey
()));
Assert
.
assertFalse
(
lowerCaseMap
.
excludes
(
e
.
getKey
()));
Assert
.
assertFalse
(
lowerCaseMap
.
excludes
(
e
.
getKey
(),
0
,
e
.
getKey
().
length
()));
int
keyIndex
=
lowerCaseMap
.
keyIndex
(
e
.
getKey
());
Assert
.
assertTrue
(
keyIndex
<
0
);
Assert
.
assertEquals
(
e
.
getKey
(),
(
int
)
e
.
getValue
(),
lowerCaseMap
.
valueAt
(
keyIndex
));
keyIndex
=
lowerCaseMap
.
keyIndex
(
e
.
getKey
(),
0
,
e
.
getKey
().
length
());
Assert
.
assertEquals
((
int
)
e
.
getValue
(),
lowerCaseMap
.
valueAt
(
keyIndex
));
}
for
(
int
i
=
0
,
n
=
lowerCaseMap
.
keys
.
length
;
i
<
n
;
i
++)
{
CharSequence
v
=
lowerCaseMap
.
keys
[
i
];
if
(
v
!=
null
)
{
Assert
.
assertTrue
(
referenceMap
.
containsKey
(
v
.
toString
()));
}
}
// remove every forth key
// make sure rnd generates the same keys again
rnd
.
reset
();
for
(
int
i
=
0
;
i
<
N
;
i
++)
{
String
s
=
rnd
.
nextString
(
4
);
if
(
i
%
4
==
0
)
{
lowerCaseMap
.
remove
(
s
);
referenceMap
.
remove
(
s
);
}
}
// verify
for
(
Map
.
Entry
<
String
,
Integer
>
e
:
referenceMap
.
entrySet
())
{
Assert
.
assertTrue
(
e
.
getKey
(),
lowerCaseMap
.
contains
(
e
.
getKey
()));
}
for
(
int
i
=
0
,
n
=
lowerCaseMap
.
keys
.
length
;
i
<
n
;
i
++)
{
CharSequence
v
=
lowerCaseMap
.
keys
[
i
];
if
(
v
!=
null
)
{
Assert
.
assertTrue
(
referenceMap
.
containsKey
(
v
.
toString
()));
}
}
}
}
\ No newline at end of file
core/src/test/java/io/questdb/std/LowerCaseCharSequenceObjHashMapTest.java
0 → 100644
浏览文件 @
86062c80
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* 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.std
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
LowerCaseCharSequenceObjHashMapTest
{
@Test
public
void
testSaturation
()
{
final
int
N
=
10_000
;
final
Rnd
rnd
=
new
Rnd
();
final
LowerCaseCharSequenceObjHashMap
<
Integer
>
lowerCaseMap
=
new
LowerCaseCharSequenceObjHashMap
<>();
final
HashMap
<
String
,
Integer
>
referenceMap
=
new
HashMap
<>();
for
(
int
i
=
0
;
i
<
N
;
i
++)
{
String
str
=
rnd
.
nextString
(
4
);
int
value
=
rnd
.
nextInt
();
int
keyIndex
=
lowerCaseMap
.
keyIndex
(
str
,
0
,
str
.
length
());
if
(
lowerCaseMap
.
put
(
str
,
value
))
{
Assert
.
assertNull
(
"at "
+
i
,
referenceMap
.
put
(
str
,
value
));
Assert
.
assertTrue
(
keyIndex
>
-
1
);
}
else
{
Assert
.
assertTrue
(
keyIndex
<
0
);
// this should fail to put
lowerCaseMap
.
putIfAbsent
(
str
,
value
);
lowerCaseMap
.
putAt
(
keyIndex
,
str
,
referenceMap
.
get
(
str
));
}
}
// verify
for
(
Map
.
Entry
<
String
,
Integer
>
e
:
referenceMap
.
entrySet
())
{
Assert
.
assertTrue
(
lowerCaseMap
.
contains
(
e
.
getKey
()));
Assert
.
assertFalse
(
lowerCaseMap
.
excludes
(
e
.
getKey
()));
Assert
.
assertFalse
(
lowerCaseMap
.
excludes
(
e
.
getKey
(),
0
,
e
.
getKey
().
length
()));
int
keyIndex
=
lowerCaseMap
.
keyIndex
(
e
.
getKey
());
Assert
.
assertTrue
(
keyIndex
<
0
);
Assert
.
assertEquals
(
e
.
getKey
(),
e
.
getValue
(),
lowerCaseMap
.
valueAt
(
keyIndex
));
keyIndex
=
lowerCaseMap
.
keyIndex
(
e
.
getKey
(),
0
,
e
.
getKey
().
length
());
Assert
.
assertEquals
(
e
.
getValue
(),
lowerCaseMap
.
valueAt
(
keyIndex
));
}
for
(
int
i
=
0
,
n
=
lowerCaseMap
.
keys
.
length
;
i
<
n
;
i
++)
{
CharSequence
v
=
lowerCaseMap
.
keys
[
i
];
if
(
v
!=
null
)
{
Assert
.
assertTrue
(
referenceMap
.
containsKey
(
v
.
toString
()));
}
}
// remove every forth key
// make sure rnd generates the same keys again
rnd
.
reset
();
for
(
int
i
=
0
;
i
<
N
;
i
++)
{
String
s
=
rnd
.
nextString
(
4
);
if
(
i
%
4
==
0
)
{
lowerCaseMap
.
remove
(
s
);
referenceMap
.
remove
(
s
);
}
}
// verify
for
(
Map
.
Entry
<
String
,
Integer
>
e
:
referenceMap
.
entrySet
())
{
Assert
.
assertTrue
(
e
.
getKey
(),
lowerCaseMap
.
contains
(
e
.
getKey
()));
}
for
(
int
i
=
0
,
n
=
lowerCaseMap
.
keys
.
length
;
i
<
n
;
i
++)
{
CharSequence
v
=
lowerCaseMap
.
keys
[
i
];
if
(
v
!=
null
)
{
Assert
.
assertTrue
(
referenceMap
.
containsKey
(
v
.
toString
()));
}
}
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录