-
Notifications
You must be signed in to change notification settings - Fork 62
v0.2 to v0.3 upgrade
yliuuuu edited this page Nov 2, 2022
·
4 revisions
- DATE and TIME data types
- Parser support for
- Multiple
SET
,REMOVE
operations per DML statement -
ON CONFLICT
andRETURNING
DML clause -
ORDER BY
clause (not yet implemented in evaluator)
- Multiple
- Redact function that removes potentially sensitive information from SQL queries, allowing them to be logged for later analysis
- Optimizes
AstNode
’sIterator
- [fix] parser handling of top-level tokens
- [fix]
SIZE
ExprFunction
to work with s-expressions - [fix] Change usage of
LazyThreadSafetyMode
fromNONE
toPUBLICATION
NOTE: ExprNode
is deprecated and replaced with PartiqlAst
. Users can look at ExprNodeToStatement.kt and RewriterToVisitorTransformGuide.md to see how to update from ExprNode
to PartiqlAst
.
- Replace
SourcePosition
inToken
withSourceSpan
// ----- v0.2.* -----
val ion = IonSystemBuilder.standard().build()
// `SqlLexer` provides us with `Token`s
val tokens = SqlLexer(ion).tokenize("42")
val firstToken = tokens.first()
// `Token`s defined in v0.2.* and before used `SourcePosition` specifying the `line` and `column` of a `Token`
val tokenFromConstructor = Token(
type = TokenType.LITERAL,
value = ion.singleValue("42"),
position = SourcePosition(
line = 1,
column = 1
)
)
assertEquals(tokenFromConstructor, firstToken)
// ----- v0.3.* -----
// `Token`s defined in v0.3.* onwards used `SourceSpan` specifying the `line`, `column`, and length of a `Token`
val tokenFromConstructor = Token(
type = TokenType.LITERAL,
value = ion.singleValue("42"),
span = SourceSpan(
line = 1,
column = 1,
length = 2
)
)
assertEquals(tokenFromConstructor, firstToken)
- Removed
PARSE_EXEC_AT_UNEXPECTED_LOCATION
error code fromErrorCode
// ----- v0.2.* -----
val ion = IonSystemBuilder.standard().build()
val parser = SqlParser(ion)
// bad query containing a stored procedure call, `EXEC`, at an unexpected location
val badQuery = "SELECT * FROM (EXEC undrop 'foo')"
try {
parser.parseExprNode(badQuery)
} catch (pe: ParserException) {
// the parser gives a `ParserException` with error code `PARSE_EXEC_AT_UNEXPECTED_LOCATION`, which is
// removed starting in v0.3.* onwards
assertEquals(ErrorCode.PARSE_EXEC_AT_UNEXPECTED_LOCATION, pe.errorCode)
}
// ----- v0.3.* -----
try {
parser.parseExprNode(badQuery)
} catch (pe: ParserException) {
// the parser gives a `ParserException` with error code `PARSE_UNEXPECTED_TERM` in v0.3.* onwards
assertEquals(ErrorCode.PARSE_UNEXPECTED_TERM, pe.errorCode)
}
- Refactoring of
ExprNode
AST
-
AssignmentOp
node stores oneAssignment
rather than a list -
DataManipulation
node stores aDmlOpList
rather than a singleDataManipulationOperation
// ----- v0.2.* -----
val ion = IonSystemBuilder.standard().build()
// In v0.2.* and before,
// - `DataManipulation` node can only specify a single `dmlOperation`
// - `AssignmentOp`, a type of `DataManipulationOperation` contains a list of `Assignments`
// The following AST represents the DML query (without source location metas): SET k = 5, l = 6
DataManipulation(
dmlOperation = AssignmentOp(
assignments = listOf(
Assignment(
lvalue = VariableReference(
id = "k",
case = CaseSensitivity.INSENSITIVE,
metas = emptyMetaContainer
),
rvalue = Literal(
ionValue = ion.singleValue("5"),
metas = emptyMetaContainer
)
),
Assignment(
lvalue = VariableReference(
id = "l",
case = CaseSensitivity.INSENSITIVE,
metas = emptyMetaContainer
),
rvalue = Literal(
ionValue = ion.singleValue("6"),
metas = emptyMetaContainer
)
)
)
),
metas = emptyMetaContainer
)
// ----- v0.3.* -----
// In v0.3.* onwards,
// - `DataManipulation` node specifies a list of `dmlOperation`s
// - `AssignmentOp`, a type of `DataManipulationOperation` contains a single assignment
// The following AST represents the DML query (without source location metas): SET k = 5, l = 6
DataManipulation(
dmlOperations = DmlOpList(
ops = listOf(
AssignmentOp(
assignment = Assignment(
lvalue = VariableReference(
id = "k",
case = CaseSensitivity.INSENSITIVE,
metas = emptyMetaContainer
),
rvalue = Literal(
ionValue = ion.singleValue("5"),
metas = emptyMetaContainer
)
)
),
AssignmentOp(
assignment = Assignment(
lvalue = VariableReference(
id = "l",
case = CaseSensitivity.INSENSITIVE,
metas = emptyMetaContainer
),
rvalue = Literal(
ionValue = ion.singleValue("6"),
metas = emptyMetaContainer
)
)
)
)
),
metas = emptyMetaContainer
)
- General
- Tutorials
- Documentation
- Clauses
- Testing
- Serde
- Upgrade Guides
- Design & Development Documents