// Test that we can resolve the names in an expression that has already been // resolved. func TestRetryResolveNames(t *testing.T) { defer leaktest.AfterTest(t)() expr, err := parser.ParseExprTraditional(`count(a)`) if err != nil { t.Fatal(err) } desc := testTableDesc() s := testInitDummySelectNode(desc) if err := desc.AllocateIDs(); err != nil { t.Fatal(err) } for i := 0; i < 2; i++ { newExpr, _, err := s.resolveNames(expr) if err != nil { t.Fatal(err) } count := 0 for iv := 0; iv < len(s.sourceInfo[0].sourceColumns); iv++ { if s.ivarHelper.IndexedVarUsed(iv) { count++ } } if count != 1 { t.Fatalf("%d: expected 1 ivar, but found %d", i, count) } if newExpr.String() != "count(a)" { t.Fatalf("%d: newExpr: got %s, expected 'count(a)'", i, newExpr.String()) } expr = newExpr } }
func parseAndNormalizeExpr(t *testing.T, sql string, sel *selectNode) parser.TypedExpr { expr, err := parser.ParseExprTraditional(sql) if err != nil { t.Fatalf("%s: %v", sql, err) } // Perform name resolution because {analyze,simplify}Expr want // expressions containing IndexedVars. if expr, err = sel.resolveNames(expr); err != nil { t.Fatalf("%s: %v", sql, err) } typedExpr, err := parser.TypeCheck(expr, nil, parser.NoTypePreference) if err != nil { t.Fatalf("%s: %v", sql, err) } ctx := &parser.EvalContext{} if typedExpr, err = ctx.NormalizeExpr(typedExpr); err != nil { t.Fatalf("%s: %v", sql, err) } return typedExpr }
func (p *planner) validateCheckExpr( exprStr string, tableName parser.TableExpr, tableDesc *sqlbase.TableDescriptor, ) error { expr, err := parser.ParseExprTraditional(exprStr) if err != nil { return err } sel := &parser.SelectClause{ Exprs: sqlbase.ColumnsSelectors(tableDesc.Columns), From: &parser.From{Tables: parser.TableExprs{tableName}}, Where: &parser.Where{Expr: &parser.NotExpr{Expr: expr}}, } lim := &parser.Limit{Count: parser.NewDInt(1)} // This could potentially use a variant of planner.SelectClause that could // use the tableDesc we have, but this is a rare operation and be benefit // would be marginal compared to the work of the actual query, so the added // complexity seems unjustified. rows, err := p.SelectClause(sel, nil, lim, nil, publicColumns) if err != nil { return err } rows, err = p.optimizePlan(rows, allColumns(rows)) if err != nil { return err } if err := p.startPlan(rows); err != nil { return err } next, err := rows.Next() if err != nil { return err } if next { return errors.Errorf("validation of CHECK %q failed on row: %s", expr.String(), labeledRowValues(tableDesc.Columns, rows.Values())) } return nil }
// processExpression parses the string expression inside an Expression, // interpreting $0, $1, etc as indexed variables. func processExpression(exprSpec Expression, h *parser.IndexedVarHelper) (parser.TypedExpr, error) { if exprSpec.Expr == "" { return nil, nil } expr, err := parser.ParseExprTraditional(exprSpec.Expr) if err != nil { return nil, err } // Convert Placeholders to IndexedVars v := valArgsConvert{h: h, err: nil} expr, _ = parser.WalkExpr(&v, expr) if v.err != nil { return nil, v.err } // Convert to a fully typed expression. typedExpr, err := parser.TypeCheck(expr, nil, parser.NoTypePreference) if err != nil { return nil, err } return typedExpr, nil }
// processExpression parses the string expression inside an Expression, // and associates ordinal references (@1, @2, etc) with the given helper. func processExpression(exprSpec Expression, h *parser.IndexedVarHelper) (parser.TypedExpr, error) { if exprSpec.Expr == "" { return nil, nil } expr, err := parser.ParseExprTraditional(exprSpec.Expr) if err != nil { return nil, err } // Bind IndexedVars to our eh.vars. v := ivarBinder{h: h, err: nil} parser.WalkExprConst(&v, expr) if v.err != nil { return nil, v.err } // Convert to a fully typed expression. typedExpr, err := parser.TypeCheck(expr, nil, parser.NoTypePreference) if err != nil { return nil, err } return typedExpr, nil }