From 2528cf300d2fa8c59f40431f6de794511cfa9014 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Tue, 11 Feb 2025 16:01:49 +0100 Subject: [PATCH] paths: do not allocate byte slices; use unsigned varints Signed-off-by: Vicent Marti --- go/tools/asthelpergen/paths_gen.go | 2 +- go/vt/sqlparser/ast_path.go | 112 ++++++++++++------------- go/vt/sqlparser/pathbuilder/builder.go | 4 +- go/vt/sqlparser/paths.go | 46 ++++++---- go/vt/sqlparser/paths_test.go | 2 +- 5 files changed, 91 insertions(+), 75 deletions(-) diff --git a/go/tools/asthelpergen/paths_gen.go b/go/tools/asthelpergen/paths_gen.go index 49ef710f15e..190db0d3916 100644 --- a/go/tools/asthelpergen/paths_gen.go +++ b/go/tools/asthelpergen/paths_gen.go @@ -256,7 +256,7 @@ func (p *pathGen) generateWalkCases(spi generatorSPI) []jen.Code { } cases = append(cases, jen.Case(jen.Id(stepName+"Offset")).Block( - jen.Id("idx, bytesRead").Op(":=").Qual("encoding/binary", "Varint").Call(jen.Index().Byte().Parens(jen.Id("path"))), + jen.Id("idx, bytesRead").Op(":=").Id("nextPathOffset").Call(jen.Id("path")), jen.Id("path").Op("=").Id("path[bytesRead:]"), jen.Return(jen.Id("GetNodeFromPath").Call(assignNode, jen.Id("path"))), )) diff --git a/go/vt/sqlparser/ast_path.go b/go/vt/sqlparser/ast_path.go index 8ea0ce55419..693908bf4fa 100644 --- a/go/vt/sqlparser/ast_path.go +++ b/go/vt/sqlparser/ast_path.go @@ -1660,7 +1660,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { path = path[2:] switch ASTStep(step) { case RefOfAddColumnsColumnsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*AddColumns).Columns[idx], path) case RefOfAddColumnsAfter: @@ -1700,7 +1700,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfAlterTableTable: return GetNodeFromPath(node.(*AlterTable).Table, path) case RefOfAlterTableAlterOptionsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*AlterTable).AlterOptions[idx], path) case RefOfAlterTablePartitionSpec: @@ -1724,7 +1724,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfAlterVschemaVindexSpec: return GetNodeFromPath(node.(*AlterVschema).VindexSpec, path) case RefOfAlterVschemaVindexColsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*AlterVschema).VindexCols[idx], path) case RefOfAlterVschemaAutoIncSpec: @@ -1776,13 +1776,13 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfCallProcName: return GetNodeFromPath(node.(*CallProc).Name, path) case RefOfCallProcParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*CallProc).Params[idx], path) case RefOfCaseExprExpr: return GetNodeFromPath(node.(*CaseExpr).Expr, path) case RefOfCaseExprWhensOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*CaseExpr).Whens[idx], path) case RefOfCaseExprElse: @@ -1798,7 +1798,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfChangeColumnAfter: return GetNodeFromPath(node.(*ChangeColumn).After, path) case RefOfCharExprExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*CharExpr).Exprs[idx], path) case RefOfCheckConstraintDefinitionExpr: @@ -1814,7 +1814,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfColumnDefinitionType: return GetNodeFromPath(node.(*ColumnDefinition).Type, path) case ColumnsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(Columns)[idx], path) case RefOfCommonTableExprID: @@ -1840,7 +1840,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfConvertUsingExprExpr: return GetNodeFromPath(node.(*ConvertUsingExpr).Expr, path) case RefOfCountArgsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*Count).Args[idx], path) case RefOfCountOverClause: @@ -1880,7 +1880,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfDeleteComments: return GetNodeFromPath(node.(*Delete).Comments, path) case RefOfDeleteTableExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*Delete).TableExprs[idx], path) case RefOfDeleteTargets: @@ -1916,7 +1916,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfExecuteStmtComments: return GetNodeFromPath(node.(*ExecuteStmt).Comments, path) case RefOfExecuteStmtArgumentsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*ExecuteStmt).Arguments[idx], path) case RefOfExistsExprSubquery: @@ -1928,7 +1928,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfExplainTabTable: return GetNodeFromPath(node.(*ExplainTab).Table, path) case RefOfExprsExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*Exprs).Exprs[idx], path) case RefOfExtractFuncExprExpr: @@ -1962,7 +1962,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfFuncExprName: return GetNodeFromPath(node.(*FuncExpr).Name, path) case RefOfFuncExprExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*FuncExpr).Exprs[idx], path) case RefOfGTIDFuncExprSet1: @@ -2022,11 +2022,11 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfGeomPropertyFuncExprGeom: return GetNodeFromPath(node.(*GeomPropertyFuncExpr).Geom, path) case RefOfGroupByExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*GroupBy).Exprs[idx], path) case RefOfGroupConcatExprExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*GroupConcatExpr).Exprs[idx], path) case RefOfGroupConcatExprOrderBy: @@ -2036,11 +2036,11 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfIndexDefinitionInfo: return GetNodeFromPath(node.(*IndexDefinition).Info, path) case RefOfIndexHintIndexesOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*IndexHint).Indexes[idx], path) case IndexHintsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(IndexHints)[idx], path) case RefOfIndexInfoName: @@ -2076,7 +2076,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfIntervalFuncExprExpr: return GetNodeFromPath(node.(*IntervalFuncExpr).Expr, path) case RefOfIntervalFuncExprExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*IntervalFuncExpr).Exprs[idx], path) case RefOfIntroducerExprExpr: @@ -2088,7 +2088,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfJSONArrayAggOverClause: return GetNodeFromPath(node.(*JSONArrayAgg).OverClause, path) case RefOfJSONArrayExprParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONArrayExpr).Params[idx], path) case RefOfJSONAttributesExprJSONDoc: @@ -2100,7 +2100,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfJSONContainsExprCandidate: return GetNodeFromPath(node.(*JSONContainsExpr).Candidate, path) case RefOfJSONContainsExprPathListOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONContainsExpr).PathList[idx], path) case RefOfJSONContainsPathExprJSONDoc: @@ -2108,13 +2108,13 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfJSONContainsPathExprOneOrAll: return GetNodeFromPath(node.(*JSONContainsPathExpr).OneOrAll, path) case RefOfJSONContainsPathExprPathListOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONContainsPathExpr).PathList[idx], path) case RefOfJSONExtractExprJSONDoc: return GetNodeFromPath(node.(*JSONExtractExpr).JSONDoc, path) case RefOfJSONExtractExprPathListOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONExtractExpr).PathList[idx], path) case RefOfJSONKeysExprJSONDoc: @@ -2128,7 +2128,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfJSONObjectAggOverClause: return GetNodeFromPath(node.(*JSONObjectAgg).OverClause, path) case RefOfJSONObjectExprParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONObjectExpr).Params[idx], path) case RefOfJSONObjectParamKey: @@ -2146,7 +2146,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfJSONRemoveExprJSONDoc: return GetNodeFromPath(node.(*JSONRemoveExpr).JSONDoc, path) case RefOfJSONRemoveExprPathListOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONRemoveExpr).PathList[idx], path) case RefOfJSONSchemaValidFuncExprSchema: @@ -2166,7 +2166,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfJSONSearchExprEscapeChar: return GetNodeFromPath(node.(*JSONSearchExpr).EscapeChar, path) case RefOfJSONSearchExprPathListOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONSearchExpr).PathList[idx], path) case RefOfJSONStorageFreeExprJSONVal: @@ -2180,7 +2180,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfJSONTableExprFilter: return GetNodeFromPath(node.(*JSONTableExpr).Filter, path) case RefOfJSONTableExprColumnsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONTableExpr).Columns[idx], path) case RefOfJSONUnquoteExprJSONValue: @@ -2198,13 +2198,13 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfJSONValueMergeExprJSONDoc: return GetNodeFromPath(node.(*JSONValueMergeExpr).JSONDoc, path) case RefOfJSONValueMergeExprJSONDocListOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONValueMergeExpr).JSONDocList[idx], path) case RefOfJSONValueModifierExprJSONDoc: return GetNodeFromPath(node.(*JSONValueModifierExpr).JSONDoc, path) case RefOfJSONValueModifierExprParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*JSONValueModifierExpr).Params[idx], path) case RefOfJoinConditionOn: @@ -2234,7 +2234,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfLimitRowcount: return GetNodeFromPath(node.(*Limit).Rowcount, path) case RefOfLineStringExprPointParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*LineStringExpr).PointParams[idx], path) case RefOfLinestrPropertyFuncExprLinestring: @@ -2252,7 +2252,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfLockingFuncTimeout: return GetNodeFromPath(node.(*LockingFunc).Timeout, path) case RefOfMatchExprColumnsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*MatchExpr).Columns[idx], path) case RefOfMatchExprExpr: @@ -2274,15 +2274,15 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfModifyColumnAfter: return GetNodeFromPath(node.(*ModifyColumn).After, path) case RefOfMultiLinestringExprLinestringParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*MultiLinestringExpr).LinestringParams[idx], path) case RefOfMultiPointExprPointParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*MultiPointExpr).PointParams[idx], path) case RefOfMultiPolygonExprPolygonParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*MultiPolygonExpr).PolygonParams[idx], path) case RefOfNTHValueExprExpr: @@ -2298,7 +2298,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfNamedWindowWindows: return GetNodeFromPath(node.(*NamedWindow).Windows, path) case NamedWindowsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(NamedWindows)[idx], path) case RefOfNextvalExpr: @@ -2312,7 +2312,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfOffsetOriginal: return GetNodeFromPath(node.(*Offset).Original, path) case OnDupOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(OnDup)[idx], path) case RefOfOptLikeLikeTable: @@ -2324,7 +2324,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfOrderExpr: return GetNodeFromPath(node.(*Order).Expr, path) case OrderByOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(OrderBy)[idx], path) case RefOfOrderByOptionCols: @@ -2358,7 +2358,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfPartitionOptionSubPartition: return GetNodeFromPath(node.(*PartitionOption).SubPartition, path) case RefOfPartitionOptionDefinitionsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*PartitionOption).Definitions[idx], path) case RefOfPartitionSpecNames: @@ -2368,13 +2368,13 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfPartitionSpecTableName: return GetNodeFromPath(node.(*PartitionSpec).TableName, path) case RefOfPartitionSpecDefinitionsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*PartitionSpec).Definitions[idx], path) case RefOfPartitionValueRangeRange: return GetNodeFromPath(node.(*PartitionValueRange).Range, path) case PartitionsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(Partitions)[idx], path) case RefOfPerformanceSchemaFuncExprArgument: @@ -2388,7 +2388,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfPointPropertyFuncExprValueToSet: return GetNodeFromPath(node.(*PointPropertyFuncExpr).ValueToSet, path) case RefOfPolygonExprLinestringParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*PolygonExpr).LinestringParams[idx], path) case RefOfPolygonPropertyFuncExprPolygon: @@ -2478,7 +2478,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfSelectWith: return GetNodeFromPath(node.(*Select).With, path) case RefOfSelectFromOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*Select).From[idx], path) case RefOfSelectComments: @@ -2500,7 +2500,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfSelectInto: return GetNodeFromPath(node.(*Select).Into, path) case RefOfSelectExprsExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*SelectExprs).Exprs[idx], path) case RefOfSetComments: @@ -2512,7 +2512,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfSetExprExpr: return GetNodeFromPath(node.(*SetExpr).Expr, path) case SetExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(SetExprs)[idx], path) case RefOfShowInternal: @@ -2570,7 +2570,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfSubPartitionDefinitionOptionsIndexDirectory: return GetNodeFromPath(node.(*SubPartitionDefinitionOptions).IndexDirectory, path) case SubPartitionDefinitionsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(SubPartitionDefinitions)[idx], path) case RefOfSubquerySelect: @@ -2586,7 +2586,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfSumOverClause: return GetNodeFromPath(node.(*Sum).OverClause, path) case TableExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(TableExprs)[idx], path) case TableNameName: @@ -2594,19 +2594,19 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case TableNameQualifier: return GetNodeFromPath(node.(TableName).Qualifier, path) case TableNamesOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(TableNames)[idx], path) case RefOfTableSpecColumnsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*TableSpec).Columns[idx], path) case RefOfTableSpecIndexesOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*TableSpec).Indexes[idx], path) case RefOfTableSpecConstraintsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*TableSpec).Constraints[idx], path) case RefOfTableSpecOptions: @@ -2642,7 +2642,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfUpdateComments: return GetNodeFromPath(node.(*Update).Comments, path) case RefOfUpdateTableExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*Update).TableExprs[idx], path) case RefOfUpdateExprs: @@ -2658,7 +2658,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfUpdateExprExpr: return GetNodeFromPath(node.(*UpdateExpr).Expr, path) case UpdateExprsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(UpdateExprs)[idx], path) case RefOfUpdateXMLExprTarget: @@ -2684,11 +2684,11 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfVStreamLimit: return GetNodeFromPath(node.(*VStream).Limit, path) case ValTupleOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(ValTuple)[idx], path) case ValuesOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(Values)[idx], path) case RefOfValuesFuncExprName: @@ -2726,7 +2726,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfVindexSpecType: return GetNodeFromPath(node.(*VindexSpec).Type, path) case RefOfVindexSpecParamsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*VindexSpec).Params[idx], path) case RefOfWeightStringFuncExprExpr: @@ -2744,13 +2744,13 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfWindowDefinitionWindowSpec: return GetNodeFromPath(node.(*WindowDefinition).WindowSpec, path) case WindowDefinitionsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(WindowDefinitions)[idx], path) case RefOfWindowSpecificationName: return GetNodeFromPath(node.(*WindowSpecification).Name, path) case RefOfWindowSpecificationPartitionClauseOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*WindowSpecification).PartitionClause[idx], path) case RefOfWindowSpecificationOrderClause: @@ -2758,7 +2758,7 @@ func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { case RefOfWindowSpecificationFrameClause: return GetNodeFromPath(node.(*WindowSpecification).FrameClause, path) case RefOfWithCTEsOffset: - idx, bytesRead := binary.Varint([]byte(path)) + idx, bytesRead := nextPathOffset(path) path = path[bytesRead:] return GetNodeFromPath(node.(*With).CTEs[idx], path) case RefOfXorExprLeft: diff --git a/go/vt/sqlparser/pathbuilder/builder.go b/go/vt/sqlparser/pathbuilder/builder.go index b694efe955d..e13c3bb38c9 100644 --- a/go/vt/sqlparser/pathbuilder/builder.go +++ b/go/vt/sqlparser/pathbuilder/builder.go @@ -52,13 +52,13 @@ func (apb *ASTPathBuilder) AddStep(step uint16) { func (apb *ASTPathBuilder) AddStepWithOffset(step uint16) { apb.sizes = append(apb.sizes, len(apb.path)) apb.path = binary.BigEndian.AppendUint16(apb.path, step) - apb.path = binary.AppendVarint(apb.path, 0) // 0 offset + apb.path = binary.AppendUvarint(apb.path, 0) // 0 offset } // ChangeOffset modifies the offset of the last step (which must have included an offset). func (apb *ASTPathBuilder) ChangeOffset(newOffset int) { pos := apb.sizes[len(apb.sizes)-1] + 2 - apb.path = binary.AppendVarint(apb.path[:pos], int64(newOffset)) + apb.path = binary.AppendUvarint(apb.path[:pos], uint64(newOffset)) } // Pop removes the last step (including offset, if any) from the path. diff --git a/go/vt/sqlparser/paths.go b/go/vt/sqlparser/paths.go index c0fa5e2e224..ba95e167227 100644 --- a/go/vt/sqlparser/paths.go +++ b/go/vt/sqlparser/paths.go @@ -17,7 +17,6 @@ limitations under the License. package sqlparser import ( - "encoding/binary" "fmt" "strings" ) @@ -27,44 +26,61 @@ import ( // Some steps (e.g., referencing a slice) consume *additional* bytes for an index type ASTPath string +// nextPathOffset is an implementation of binary.Uvarint that works directly on +// the ASTPath without having to cast and allocate a byte slice +func nextPathOffset(buf ASTPath) (uint64, int) { + var x uint64 + var s uint + for i := 0; i < len(buf); i++ { + b := buf[i] + if b < 0x80 { + return x | uint64(b)<= 2 { - // Read the step code (2 bytes) - stepVal := binary.BigEndian.Uint16(remaining[:2]) - remaining = remaining[2:] - - step := ASTStep(stepVal) - stepStr := step.DebugString() // e.g. "CaseExprWhens8" or "CaseExprWhens32" - + for len(path) >= 2 { // If this isn't the very first step in the path, prepend a separator if stepCount > 0 { sb.WriteString("->") } stepCount++ + // Read the step code (2 bytes) + step := nextPathStep(path) + path = path[2:] + // Write the step name + stepStr := step.DebugString() sb.WriteString(stepStr) // Check suffix to see if we need to read an offset switch { case strings.HasSuffix(stepStr, "Offset"): - if len(remaining) < 1 { + if len(path) < 1 { sb.WriteString("(ERR-no-offset-byte)") return sb.String() } - offset, readBytes := binary.Varint(remaining) - remaining = remaining[readBytes:] + offset, readBytes := nextPathOffset(path) + path = path[readBytes:] sb.WriteString(fmt.Sprintf("(%d)", offset)) } } // If there's leftover data that doesn't fit into 2 (or more) bytes, you could note it: - if len(remaining) != 0 { + if len(path) != 0 { sb.WriteString("->(ERR-unaligned-extra-bytes)") } diff --git a/go/vt/sqlparser/paths_test.go b/go/vt/sqlparser/paths_test.go index d28b33281af..14de7101854 100644 --- a/go/vt/sqlparser/paths_test.go +++ b/go/vt/sqlparser/paths_test.go @@ -33,7 +33,7 @@ func AddStep(path ASTPath, step ASTStep) ASTPath { func AddStepWithOffset(path ASTPath, step ASTStep, offset int) ASTPath { var buf [10]byte binary.BigEndian.PutUint16(buf[0:], uint16(step)) - n := binary.PutVarint(buf[2:], int64(offset)) + n := binary.PutUvarint(buf[2:], uint64(offset)) return path + ASTPath(buf[:2+n]) }