本文整理汇总了Golang中github.com/cockroachdb/cockroach/pkg/sql/parser.ReNormalizeName函数的典型用法代码示例。如果您正苦于以下问题:Golang ReNormalizeName函数的具体用法?Golang ReNormalizeName怎么用?Golang ReNormalizeName使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了ReNormalizeName函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: commonColumns
// commonColumns returns the names of columns common on the
// right and left sides, for use by NATURAL JOIN.
func commonColumns(left, right *dataSourceInfo) parser.NameList {
var res parser.NameList
for _, cLeft := range left.sourceColumns {
if cLeft.hidden {
continue
}
for _, cRight := range right.sourceColumns {
if cRight.hidden {
continue
}
if parser.ReNormalizeName(cLeft.Name) == parser.ReNormalizeName(cRight.Name) {
res = append(res, parser.Name(cLeft.Name))
}
}
}
return res
}
开发者ID:maxlang,项目名称:cockroach,代码行数:20,代码来源:join.go
示例2: upsertExprsAndIndex
// upsertExprsAndIndex returns the upsert conflict index and the (possibly
// synthetic) SET expressions used when a row conflicts.
func upsertExprsAndIndex(
tableDesc *sqlbase.TableDescriptor,
onConflict parser.OnConflict,
insertCols []sqlbase.ColumnDescriptor,
) (parser.UpdateExprs, *sqlbase.IndexDescriptor, error) {
if onConflict.IsUpsertAlias() {
// The UPSERT syntactic sugar is the same as the longhand specifying the
// primary index as the conflict index and SET expressions for the columns
// in insertCols minus any columns in the conflict index. Example:
// `UPSERT INTO abc VALUES (1, 2, 3)` is syntactic sugar for
// `INSERT INTO abc VALUES (1, 2, 3) ON CONFLICT a DO UPDATE SET b = 2, c = 3`.
conflictIndex := &tableDesc.PrimaryIndex
indexColSet := make(map[sqlbase.ColumnID]struct{}, len(conflictIndex.ColumnIDs))
for _, colID := range conflictIndex.ColumnIDs {
indexColSet[colID] = struct{}{}
}
updateExprs := make(parser.UpdateExprs, 0, len(insertCols))
for _, c := range insertCols {
if _, ok := indexColSet[c.ID]; !ok {
names := parser.UnresolvedNames{
parser.UnresolvedName{parser.Name(c.Name)},
}
expr := &parser.ColumnItem{
TableName: upsertExcludedTable,
ColumnName: parser.Name(c.Name),
}
updateExprs = append(updateExprs, &parser.UpdateExpr{Names: names, Expr: expr})
}
}
return updateExprs, conflictIndex, nil
}
indexMatch := func(index sqlbase.IndexDescriptor) bool {
if !index.Unique {
return false
}
if len(index.ColumnNames) != len(onConflict.Columns) {
return false
}
for i, colName := range index.ColumnNames {
if parser.ReNormalizeName(colName) != onConflict.Columns[i].Normalize() {
return false
}
}
return true
}
if indexMatch(tableDesc.PrimaryIndex) {
return onConflict.Exprs, &tableDesc.PrimaryIndex, nil
}
for _, index := range tableDesc.Indexes {
if indexMatch(index) {
return onConflict.Exprs, &index, nil
}
}
return nil, nil, fmt.Errorf("there is no unique or exclusion constraint matching the ON CONFLICT specification")
}
开发者ID:knz,项目名称:cockroach,代码行数:59,代码来源:upsert.go
示例3: MakeNameMetadataKey
// MakeNameMetadataKey returns the key for the name. Pass name == "" in order
// to generate the prefix key to use to scan over all of the names for the
// specified parentID.
func MakeNameMetadataKey(parentID ID, name string) roachpb.Key {
normName := parser.ReNormalizeName(name)
k := keys.MakeTablePrefix(uint32(NamespaceTable.ID))
k = encoding.EncodeUvarintAscending(k, uint64(NamespaceTable.PrimaryIndex.ID))
k = encoding.EncodeUvarintAscending(k, uint64(parentID))
if name != "" {
k = encoding.EncodeBytesAscending(k, []byte(normName))
k = keys.MakeFamilyKey(k, uint32(NamespaceTable.Columns[2].ID))
}
return k
}
开发者ID:knz,项目名称:cockroach,代码行数:14,代码来源:keys.go
示例4: findUnaliasedColumn
// findUnaliasedColumn looks up the column specified by a VarName, not
// taking column renames into account (but table renames will be taken
// into account). That is, given a table "blah" with single column "y",
// findUnaliasedColumn("y") returns a valid index even in the context
// of:
// SELECT * FROM blah as foo(x)
// If the VarName specifies a table name, only columns that have that
// name as their source alias are considered. If the VarName does not
// specify a table name, all columns in the data source are
// considered. If no column is found, invalidColIdx is returned with
// no error.
func (p *planDataSource) findUnaliasedColumn(c *parser.ColumnItem) (colIdx int, err error) {
colName := c.ColumnName.Normalize()
tableName := c.TableName.NormalizedTableName()
if tableName.Table() != "" {
tn, err := p.info.checkDatabaseName(tableName)
if err != nil {
return invalidColIdx, nil
}
tableName = tn
}
colIdx = invalidColIdx
planColumns := p.plan.Columns()
selCol := func(colIdx int, idx int) (int, error) {
col := planColumns[idx]
if parser.ReNormalizeName(col.Name) == colName {
if colIdx != invalidColIdx {
return invalidColIdx, fmt.Errorf("column reference %q is ambiguous", c)
}
colIdx = idx
}
return colIdx, nil
}
if tableName.Table() == "" {
for idx := 0; idx < len(p.info.sourceColumns); idx++ {
colIdx, err = selCol(colIdx, idx)
if err != nil {
return colIdx, err
}
}
} else {
colRange, ok := p.info.sourceAliases[tableName]
if !ok {
// A table name is specified, but there is no column with this
// table name.
return invalidColIdx, nil
}
for _, idx := range colRange {
colIdx, err = selCol(colIdx, idx)
if err != nil {
return colIdx, err
}
}
}
return colIdx, nil
}
开发者ID:knz,项目名称:cockroach,代码行数:61,代码来源:data_source.go
示例5: makeColIDtoRowIndex
func makeColIDtoRowIndex(
row planNode, desc *sqlbase.TableDescriptor,
) (map[sqlbase.ColumnID]int, error) {
columns := row.Columns()
colIDtoRowIndex := make(map[sqlbase.ColumnID]int, len(columns))
for i, column := range columns {
s, idx, err := desc.FindColumnByNormalizedName(parser.ReNormalizeName(column.Name))
if err != nil {
return nil, err
}
switch s {
case sqlbase.DescriptorActive:
colIDtoRowIndex[desc.Columns[idx].ID] = i
case sqlbase.DescriptorIncomplete:
colIDtoRowIndex[desc.Mutations[idx].GetColumn().ID] = i
default:
panic("unreachable")
}
}
return colIDtoRowIndex, nil
}
开发者ID:knz,项目名称:cockroach,代码行数:21,代码来源:backfill.go
示例6: getTableLease
// getTableLease implements the SchemaAccessor interface.
func (p *planner) getTableLease(tn *parser.TableName) (*sqlbase.TableDescriptor, error) {
if log.V(2) {
log.Infof(p.ctx(), "planner acquiring lease on table '%s'", tn)
}
isSystemDB := tn.Database() == sqlbase.SystemDB.Name
isVirtualDB := p.session.virtualSchemas.isVirtualDatabase(tn.Database())
if isSystemDB || isVirtualDB || testDisableTableLeases {
// We don't go through the normal lease mechanism for:
// - system tables. The system.lease and system.descriptor table, in
// particular, are problematic because they are used for acquiring
// leases itself, creating a chicken&egg problem.
// - virtual tables. These tables' descriptors are not persisted,
// so they cannot be leased. Instead, we simply return the static
// descriptor and rely on the immutability privileges set on the
// descriptors to cause upper layers to reject mutations statements.
tbl, err := p.mustGetTableDesc(tn)
if err != nil {
return nil, err
}
if err := filterTableState(tbl); err != nil {
return nil, err
}
return tbl, nil
}
dbID, err := p.getDatabaseID(tn.Database())
if err != nil {
return nil, err
}
// First, look to see if we already have a lease for this table.
// This ensures that, once a SQL transaction resolved name N to id X, it will
// continue to use N to refer to X even if N is renamed during the
// transaction.
var lease *LeaseState
for _, l := range p.leases {
if parser.ReNormalizeName(l.Name) == tn.TableName.Normalize() &&
l.ParentID == dbID {
lease = l
if log.V(2) {
log.Infof(p.ctx(), "found lease in planner cache for table '%s'", tn)
}
break
}
}
// If we didn't find a lease or the lease is about to expire, acquire one.
if lease == nil || p.removeLeaseIfExpiring(lease) {
var err error
lease, err = p.leaseMgr.AcquireByName(p.txn, dbID, tn.Table())
if err != nil {
if err == sqlbase.ErrDescriptorNotFound {
// Transform the descriptor error into an error that references the
// table's name.
return nil, sqlbase.NewUndefinedTableError(tn.String())
}
return nil, err
}
p.leases = append(p.leases, lease)
if log.V(2) {
log.Infof(p.ctx(), "added lease on table '%s' to planner cache", tn)
}
// If the lease we just acquired expires before the txn's deadline, reduce
// the deadline.
p.txn.UpdateDeadlineMaybe(hlc.Timestamp{WallTime: lease.Expiration().UnixNano()})
}
return &lease.TableDescriptor, nil
}
开发者ID:BramGruneir,项目名称:cockroach,代码行数:70,代码来源:table.go
示例7: orderBy
// orderBy constructs a sortNode based on the ORDER BY clause.
//
// In the general case (SELECT/UNION/VALUES), we can sort by a column index or a
// column name.
//
// However, for a SELECT, we can also sort by the pre-alias column name (SELECT
// a AS b ORDER BY b) as well as expressions (SELECT a, b, ORDER BY a+b). In
// this case, construction of the sortNode might adjust the number of render
// targets in the selectNode if any ordering expressions are specified.
//
// TODO(dan): SQL also allows sorting a VALUES or UNION by an expression.
// Support this. It will reduce some of the special casing below, but requires a
// generalization of how to add derived columns to a SelectStatement.
func (p *planner) orderBy(orderBy parser.OrderBy, n planNode) (*sortNode, error) {
if orderBy == nil {
return nil, nil
}
// Multiple tests below use selectNode as a special case.
// So factor the cast.
s, _ := n.(*selectNode)
// We grab a copy of columns here because we might add new render targets
// below. This is the set of columns requested by the query.
columns := n.Columns()
numOriginalCols := len(columns)
if s != nil {
numOriginalCols = s.numOriginalCols
}
var ordering sqlbase.ColumnOrdering
for _, o := range orderBy {
direction := encoding.Ascending
if o.Direction == parser.Descending {
direction = encoding.Descending
}
index := -1
// Unwrap parenthesized expressions like "((a))" to "a".
expr := parser.StripParens(o.Expr)
// The logical data source for ORDER BY is the list of render
// expressions for a SELECT, as specified in the input SQL text
// (or an entire UNION or VALUES clause). Alas, SQL has some
// historical baggage from SQL92 and there are some special cases:
//
// SQL92 rules:
//
// 1) if the expression is the aliased (AS) name of a render
// expression in a SELECT clause, then use that
// render as sort key.
// e.g. SELECT a AS b, b AS c ORDER BY b
// this sorts on the first render.
//
// 2) column ordinals. If a simple integer literal is used,
// optionally enclosed within parentheses but *not subject to
// any arithmetic*, then this refers to one of the columns of
// the data source. Then use the render expression at that
// ordinal position as sort key.
//
// SQL99 rules:
//
// 3) otherwise, if the expression is already in the render list,
// then use that render as sort key.
// e.g. SELECT b AS c ORDER BY b
// this sorts on the first render.
// (this is an optimization)
//
// 4) if the sort key is not dependent on the data source (no
// IndexedVar) then simply do not sort. (this is an optimization)
//
// 5) otherwise, add a new render with the ORDER BY expression
// and use that as sort key.
// e.g. SELECT a FROM t ORDER by b
// e.g. SELECT a, b FROM t ORDER by a+b
// First, deal with render aliases.
if vBase, ok := expr.(parser.VarName); index == -1 && ok {
v, err := vBase.NormalizeVarName()
if err != nil {
return nil, err
}
if c, ok := v.(*parser.ColumnItem); ok && c.TableName.Table() == "" {
// Look for an output column that matches the name. This
// handles cases like:
//
// SELECT a AS b FROM t ORDER BY b
target := c.ColumnName.Normalize()
for j, col := range columns {
if parser.ReNormalizeName(col.Name) == target {
if index != -1 {
// There is more than one render alias that matches the ORDER BY
// clause. Here, SQL92 is specific as to what should be done:
// if the underlying expression is known (we're on a selectNode)
// and it is equivalent, then just accept that and ignore the ambiguity.
// This plays nice with `SELECT b, * FROM t ORDER BY b`. Otherwise,
// reject with an ambituity error.
if s == nil || !s.equivalentRenders(j, index) {
//.........这里部分代码省略.........
开发者ID:BramGruneir,项目名称:cockroach,代码行数:101,代码来源:sort.go
示例8: makeUpsertHelper
func (p *planner) makeUpsertHelper(
tn *parser.TableName,
tableDesc *sqlbase.TableDescriptor,
insertCols []sqlbase.ColumnDescriptor,
updateCols []sqlbase.ColumnDescriptor,
updateExprs parser.UpdateExprs,
upsertConflictIndex *sqlbase.IndexDescriptor,
) (*upsertHelper, error) {
defaultExprs, err := makeDefaultExprs(updateCols, &p.parser, &p.evalCtx)
if err != nil {
return nil, err
}
untupledExprs := make(parser.Exprs, 0, len(updateExprs))
i := 0
for _, updateExpr := range updateExprs {
if updateExpr.Tuple {
if t, ok := updateExpr.Expr.(*parser.Tuple); ok {
for _, e := range t.Exprs {
typ := updateCols[i].Type.ToDatumType()
e := fillDefault(e, typ, i, defaultExprs)
untupledExprs = append(untupledExprs, e)
i++
}
}
} else {
typ := updateCols[i].Type.ToDatumType()
e := fillDefault(updateExpr.Expr, typ, i, defaultExprs)
untupledExprs = append(untupledExprs, e)
i++
}
}
sourceInfo := newSourceInfoForSingleTable(*tn, makeResultColumns(tableDesc.Columns))
excludedSourceInfo := newSourceInfoForSingleTable(upsertExcludedTable, makeResultColumns(insertCols))
helper := &upsertHelper{
p: p,
sourceInfo: sourceInfo,
excludedSourceInfo: excludedSourceInfo,
}
var evalExprs []parser.TypedExpr
ivarHelper := parser.MakeIndexedVarHelper(helper, len(sourceInfo.sourceColumns)+len(excludedSourceInfo.sourceColumns))
sources := multiSourceInfo{sourceInfo, excludedSourceInfo}
for _, expr := range untupledExprs {
normExpr, err := p.analyzeExpr(expr, sources, ivarHelper, parser.NoTypePreference, false, "")
if err != nil {
return nil, err
}
evalExprs = append(evalExprs, normExpr)
}
helper.evalExprs = evalExprs
helper.allExprsIdentity = true
for i, expr := range evalExprs {
// analyzeExpr above has normalized all direct column names to ColumnItems.
c, ok := expr.(*parser.ColumnItem)
if !ok {
helper.allExprsIdentity = false
break
}
if len(c.Selector) > 0 ||
!c.TableName.TableName.Equal(upsertExcludedTable.TableName) ||
c.ColumnName.Normalize() != parser.ReNormalizeName(updateCols[i].Name) {
helper.allExprsIdentity = false
break
}
}
return helper, nil
}
开发者ID:knz,项目名称:cockroach,代码行数:72,代码来源:upsert.go
示例9: Set
// Set sets session variables.
// Privileges: None.
// Notes: postgres/mysql do not require privileges for session variables (some exceptions).
func (p *planner) Set(n *parser.Set) (planNode, error) {
if n.Name == nil {
// A client has sent the reserved internal syntax SET ROW ...
// Reject it.
return nil, errors.New("invalid statement: SET ROW")
}
// By using VarName.String() here any variables that are keywords will
// be double quoted.
name := strings.ToUpper(n.Name.String())
typedValues := make([]parser.TypedExpr, len(n.Values))
for i, expr := range n.Values {
typedValue, err := parser.TypeCheck(expr, nil, parser.TypeString)
if err != nil {
return nil, err
}
typedValues[i] = typedValue
}
switch name {
case `DATABASE`:
dbName, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
if len(dbName) != 0 {
// Verify database descriptor exists.
if _, err := p.mustGetDatabaseDesc(dbName); err != nil {
return nil, err
}
}
p.session.Database = dbName
p.evalCtx.Database = dbName
case `SYNTAX`:
s, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
switch parser.Name(s).Normalize() {
case parser.ReNormalizeName(parser.Modern.String()):
p.session.Syntax = int32(parser.Modern)
case parser.ReNormalizeName(parser.Traditional.String()):
p.session.Syntax = int32(parser.Traditional)
default:
return nil, fmt.Errorf("%s: \"%s\" is not in (%q, %q)", name, s, parser.Modern, parser.Traditional)
}
case `EXTRA_FLOAT_DIGITS`:
// These settings are sent by the JDBC driver but we silently ignore them.
case `APPLICATION_NAME`:
// These settings are sent by the clients to improve query logging on the server,
// but we silently ignore them.
case `DEFAULT_TRANSACTION_ISOLATION`:
// It's unfortunate that clients want us to support both SET
// SESSION CHARACTERISTICS AS TRANSACTION ..., which takes the
// isolation level as keywords/identifiers (e.g. JDBC), and SET
// DEFAULT_TRANSACTION_ISOLATION TO '...', which takes an
// expression (e.g. psycopg2). But that's how it is. Just ensure
// this code keeps in sync with SetDefaultIsolation() below.
s, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
switch strings.ToUpper(s) {
case `READ UNCOMMITTED`, `READ COMMITTED`, `SNAPSHOT`:
p.session.DefaultIsolationLevel = enginepb.SNAPSHOT
case `REPEATABLE READ`, `SERIALIZABLE`:
p.session.DefaultIsolationLevel = enginepb.SERIALIZABLE
default:
return nil, fmt.Errorf("%s: unknown isolation level: %q", name, s)
}
case `DIST_SQL`:
s, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
switch parser.Name(s).Normalize() {
case parser.ReNormalizeName("sync"):
p.session.DistSQLMode = distSQLSync
case parser.ReNormalizeName("async"):
p.session.DistSQLMode = distSQLAsync
default:
return nil, fmt.Errorf("%s: \"%s\" not supported", name, s)
}
default:
return nil, fmt.Errorf("unknown variable: %q", name)
}
return &emptyNode{}, nil
}
开发者ID:hvaara,项目名称:cockroach,代码行数:96,代码来源:set.go
示例10: findColumn
// findColumn looks up the column specified by a ColumnItem. The
// function returns the index of the source in the multiSourceInfo
// array and the column index for the column array of that
// source. Returns invalid indices and an error if the source is not
// found or the name is ambiguous.
func (sources multiSourceInfo) findColumn(c *parser.ColumnItem) (srcIdx int, colIdx int, err error) {
if len(c.Selector) > 0 {
return invalidSrcIdx, invalidColIdx, util.UnimplementedWithIssueErrorf(8318, "compound types not supported yet: %q", c)
}
colName := c.ColumnName.Normalize()
var tableName parser.TableName
if c.TableName.Table() != "" {
tableName = c.TableName.NormalizedTableName()
tn, err := sources.checkDatabaseName(tableName)
if err != nil {
return invalidSrcIdx, invalidColIdx, err
}
tableName = tn
// Propagate the discovered database name back to the original VarName.
// (to clarify the output of e.g. EXPLAIN)
c.TableName.DatabaseName = tableName.DatabaseName
}
colIdx = invalidColIdx
for iSrc, src := range sources {
findColHelper := func(src *dataSourceInfo, iSrc, srcIdx, colIdx int, idx int) (int, int, error) {
col := src.sourceColumns[idx]
if parser.ReNormalizeName(col.Name) == colName {
if colIdx != invalidColIdx {
return invalidSrcIdx, invalidColIdx, fmt.Errorf("column reference %q is ambiguous", c)
}
srcIdx = iSrc
colIdx = idx
}
return srcIdx, colIdx, nil
}
if tableName.Table() == "" {
for idx := 0; idx < len(src.sourceColumns); idx++ {
srcIdx, colIdx, err = findColHelper(src, iSrc, srcIdx, colIdx, idx)
if err != nil {
return srcIdx, colIdx, err
}
}
} else {
colRange, ok := src.sourceAliases[tableName]
if !ok {
// The data source "src" has no column for table tableName.
// Try again with the net one.
continue
}
for _, idx := range colRange {
srcIdx, colIdx, err = findColHelper(src, iSrc, srcIdx, colIdx, idx)
if err != nil {
return srcIdx, colIdx, err
}
}
}
}
if colIdx == invalidColIdx {
return invalidSrcIdx, invalidColIdx, fmt.Errorf("column name %q not found", c)
}
return srcIdx, colIdx, nil
}
开发者ID:knz,项目名称:cockroach,代码行数:69,代码来源:data_source.go
示例11: nameMatchesLease
func nameMatchesLease(lease *LeaseState, dbID sqlbase.ID, tableName string) bool {
return lease.ParentID == dbID &&
parser.ReNormalizeName(lease.Name) == parser.ReNormalizeName(tableName)
}
开发者ID:jmptrader,项目名称:cockroach,代码行数:4,代码来源:lease.go
示例12: makeTableNameCacheKey
func makeTableNameCacheKey(dbID sqlbase.ID, tableName string) tableNameCacheKey {
return tableNameCacheKey{dbID, parser.ReNormalizeName(tableName)}
}
开发者ID:jmptrader,项目名称:cockroach,代码行数:3,代码来源:lease.go
示例13: orderBy
// orderBy constructs a sortNode based on the ORDER BY clause.
//
// In the general case (SELECT/UNION/VALUES), we can sort by a column index or a
// column name.
//
// However, for a SELECT, we can also sort by the pre-alias column name (SELECT
// a AS b ORDER BY b) as well as expressions (SELECT a, b, ORDER BY a+b). In
// this case, construction of the sortNode might adjust the number of render
// targets in the selectNode if any ordering expressions are specified.
//
// TODO(dan): SQL also allows sorting a VALUES or UNION by an expression.
// Support this. It will reduce some of the special casing below, but requires a
// generalization of how to add derived columns to a SelectStatement.
func (p *planner) orderBy(orderBy parser.OrderBy, n planNode) (*sortNode, error) {
if orderBy == nil {
return nil, nil
}
// Multiple tests below use selectNode as a special case.
// So factor the cast.
s, _ := n.(*selectNode)
// We grab a copy of columns here because we might add new render targets
// below. This is the set of columns requested by the query.
columns := n.Columns()
numOriginalCols := len(columns)
if s != nil {
numOriginalCols = s.numOriginalCols
}
var ordering sqlbase.ColumnOrdering
for _, o := range orderBy {
direction := encoding.Ascending
if o.Direction == parser.Descending {
direction = encoding.Descending
}
index := -1
// Unwrap parenthesized expressions like "((a))" to "a".
expr := parser.StripParens(o.Expr)
// The logical data source for ORDER BY is the list of render
// expressions for a SELECT, as specified in the input SQL text
// (or an entire UNION or VALUES clause). Alas, SQL has some
// historical baggage and there are some special cases:
//
// 1) column ordinals. If a simple integer literal is used,
// optionally enclosed within parentheses but *not subject to
// any arithmetic*, then this refers to one of the columns of
// the data source. Then use the render expression at that
// ordinal position as sort key.
//
// 2) if the expression is the aliased (AS) name of a render
// expression in a SELECT clause, then use that
// render as sort key.
// e.g. SELECT a AS b, b AS c ORDER BY b
// this sorts on the first render.
//
// 3) otherwise, if the expression is already in the render list,
// then use that render as sort key.
// e.g. SELECT b AS c ORDER BY b
// this sorts on the first render.
// (this is an optimization)
//
// 4) if the sort key is not dependent on the data source (no
// IndexedVar) then simply do not sort. (this is an optimization)
//
// 5) otherwise, add a new render with the ORDER BY expression
// and use that as sort key.
// e.g. SELECT a FROM t ORDER by b
// e.g. SELECT a, b FROM t ORDER by a+b
//
// So first, deal with column ordinals.
col, err := p.colIndex(numOriginalCols, expr, "ORDER BY")
if err != nil {
return nil, err
}
if col != -1 {
index = col
}
// Now, deal with render aliases.
if vBase, ok := expr.(parser.VarName); index == -1 && ok {
v, err := vBase.NormalizeVarName()
if err != nil {
return nil, err
}
if c, ok := v.(*parser.ColumnItem); ok && c.TableName.Table() == "" {
// Look for an output column that matches the name. This
// handles cases like:
//
// SELECT a AS b FROM t ORDER BY b
target := c.ColumnName.Normalize()
for j, col := range columns {
if parser.ReNormalizeName(col.Name) == target {
index = j
break
}
//.........这里部分代码省略.........
开发者ID:veteranlu,项目名称:cockroach,代码行数:101,代码来源:sort.go
示例14: orderBy
// orderBy constructs a sortNode based on the ORDER BY clause.
//
// In the general case (SELECT/UNION/VALUES), we can sort by a column index or a
// column name.
//
// However, for a SELECT, we can also sort by the pre-alias column name (SELECT
// a AS b ORDER BY b) as well as expressions (SELECT a, b, ORDER BY a+b). In
// this case, construction of the sortNode might adjust the number of render
// targets in the selectNode if any ordering expressions are specified.
//
// TODO(dan): SQL also allows sorting a VALUES or UNION by an expression.
// Support this. It will reduce some of the special casing below, but requires a
// generalization of how to add derived columns to a SelectStatement.
func (p *planner) orderBy(orderBy parser.OrderBy, n planNode) (*sortNode, error) {
if orderBy == nil {
return nil, nil
}
// We grab a copy of columns here because we might add new render targets
// below. This is the set of columns requested by the query.
columns := n.Columns()
numOriginalCols := len(columns)
if s, ok := n.(*selectNode); ok {
numOriginalCols = s.numOriginalCols
}
var ordering sqlbase.ColumnOrdering
for _, o := range orderBy {
index := -1
// Unwrap parenthesized expressions like "((a))" to "a".
expr := parser.StripParens(o.Expr)
if vBase, ok := expr.(parser.VarName); ok {
v, err := vBase.NormalizeVarName()
if err != nil {
return nil, err
}
var c *parser.ColumnItem
switch t := v.(type) {
case *parser.ColumnItem:
c = t
default:
return nil, fmt.Errorf("invalid syntax for ORDER BY: %s", v)
}
if c.TableName.Table() == "" {
// Look for an output column that matches the name. This
// handles cases like:
//
// SELECT a AS b FROM t ORDER BY b
target := c.ColumnName.Normalize()
for j, col := range columns {
if parser.ReNormalizeName(col.Name) == target {
index = j
break
}
}
}
if s, ok := n.(*selectNode); ok && index == -1 {
// No output column matched the name, so look for an existing
// render target that matches the column name. This handles cases like:
//
// SELECT a AS b FROM t ORDER BY a
colIdx, err := s.source.findUnaliasedColumn(c)
if err != nil {
return nil, err
}
if colIdx != invalidColIdx {
for j, r := range s.render {
if ivar, ok := r.(*parser.IndexedVar); ok {
s.ivarHelper.AssertSameContainer(ivar)
if ivar.Idx == colIdx {
index = j
break
}
}
}
}
}
}
if index == -1 {
// The order by expression matched neither an output column nor an
// existing render target.
if col, err := colIndex(numOriginalCols, expr); err != nil {
return nil, err
} else if col >= 0 {
index = col
} else if s, ok := n.(*selectNode); ok {
// TODO(dan): Once we support VALUES (1), (2) ORDER BY 3*4, this type
// check goes away.
// Add a new render expression to use for ordering. This
// handles cases were the expression is either not a name or
// is a name that is otherwise not referenced by the query:
//
// SELECT a FROM t ORDER by b
//.........这里部分代码省略.........
开发者ID:knz,项目名称:cockroach,代码行数:101,代码来源:sort.go
示例15: Set
// Set sets session variables.
// Privileges: None.
// Notes: postgres/mysql do not require privileges for session variables (some exceptions).
func (p *planner) Set(n *parser.Set) (planNode, error) {
if n.Name == nil {
// A client has sent the reserved internal syntax SET ROW ...
// Reject it.
return nil, errors.New("invalid statement: SET ROW")
}
// By using VarName.String() here any variables that are keywords will
// be double quoted.
name := strings.ToUpper(n.Name.String())
typedValues := make([]parser.TypedExpr, len(n.Values))
for i, expr := range n.Values {
typedValue, err := parser.TypeCheck(expr, nil, parser.TypeString)
if err != nil {
return nil, err
}
typedValues[i] = typedValue
}
switch name {
case `DATABASE`:
dbName, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
if len(dbName) != 0 {
// Verify database descriptor exists.
if _, err := p.mustGetDatabaseDesc(dbName); err != nil {
return nil, err
}
}
p.session.Database = dbName
p.evalCtx.Database = dbName
case `SYNTAX`:
s, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
switch parser.Name(s).Normalize() {
case parser.ReNormalizeName(parser.Modern.String()):
p.session.Syntax = int32(parser.Modern)
case parser.ReNormalizeName(parser.Traditional.String()):
p.session.Syntax = int32(parser.Traditional)
default:
return nil, fmt.Errorf("%s: \"%s\" is not in (%q, %q)", name, s, parser.Modern, parser.Traditional)
}
case `DEFAULT_TRANSACTION_ISOLATION`:
// It's unfortunate that clients want us to support both SET
// SESSION CHARACTERISTICS AS TRANSACTION ..., which takes the
// isolation level as keywords/identifiers (e.g. JDBC), and SET
// DEFAULT_TRANSACTION_ISOLATION TO '...', which takes an
// expression (e.g. psycopg2). But that's how it is. Just ensure
// this code keeps in sync with SetDefaultIsolation() below.
s, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
switch strings.ToUpper(s) {
case `READ UNCOMMITTED`, `READ COMMITTED`, `SNAPSHOT`:
p.session.DefaultIsolationLevel = enginepb.SNAPSHOT
case `REPEATABLE READ`, `SERIALIZABLE`:
p.session.DefaultIsolationLevel = enginepb.SERIALIZABLE
default:
return nil, fmt.Errorf("%s: unknown isolation level: %q", name, s)
}
case `DIST_SQL`:
s, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
switch parser.Name(s).Normalize() {
case parser.ReNormalizeName("off"):
p.session.DistSQLMode = distSQLOff
case parser.ReNormalizeName("on"):
p.session.DistSQLMode = distSQLOn
case parser.ReNormalizeName("always"):
p.session.DistSQLMode = distSQLAlways
default:
return nil, fmt.Errorf("%s: \"%s\" not supported", name, s)
}
// These settings are sent by various client drivers. We don't support
// changing them, so we either silently ignore them or throw an error given
// a setting that we do not respect.
case `EXTRA_FLOAT_DIGITS`:
// See https://www.postgresql.org/docs/9.6/static/runtime-config-client.html
case `APPLICATION_NAME`:
// Set by clients to improve query logging.
// See https://www.postgresql.org/docs/9.6/static/runtime-config-logging.html#GUC-APPLICATION-NAME
case `CLIENT_ENCODING`:
// See https://www.postgresql.org/docs/9.6/static/multibyte.html
s, err := p.getStringVal(name, typedValues)
if err != nil {
return nil, err
}
//.........这里部分代码省略.........
开发者ID:BramGruneir,项目名称:cockroach,代码行数:101,代码来源:set.go
注:本文中的github.com/cockroachdb/cockroach/pkg/sql/parser.ReNormalizeName函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论