Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Expression Indexes and Operator Classes support for PostgreSQL #23393

Closed
wants to merge 1 commit into from

Conversation

kamipo
Copy link
Member

@kamipo kamipo commented Feb 1, 2016

Example:

create_table :users do |t|
  t.string :name
  t.index 'lower(name) varchar_pattern_ops'
end

Fixes #19090.
Fixes #21765.
Fixes #21819.
Fixes #24359.

@rails-bot
Copy link

r? @kaspth

(@rails-bot has picked a reviewer for you, use r? to override)

@kamipo kamipo force-pushed the expression_index_support branch 5 times, most recently from 90a0bb8 to 807cf0c Compare February 6, 2016 08:08
@kamipo
Copy link
Member Author

kamipo commented Feb 6, 2016

r? @rafaelfranca

@rails-bot rails-bot assigned rafaelfranca and unassigned kaspth Feb 6, 2016
@kamipo kamipo force-pushed the expression_index_support branch 3 times, most recently from e7ca3b4 to 790b9ca Compare February 13, 2016 20:17
@kamipo kamipo force-pushed the expression_index_support branch 2 times, most recently from bcb0904 to 82b0ba4 Compare February 18, 2016 02:52
@kamipo kamipo changed the title Add Expression Indexes support for PostgreSQL Add Expression Indexes and Operator Classes support for PostgreSQL Mar 6, 2016
@kamipo
Copy link
Member Author

kamipo commented Mar 6, 2016

Added opclasses support.

@jeremy
Copy link
Member

jeremy commented Apr 19, 2016

Using a proc suggests that we expect a dynamic result, rather than using the special value to indicate an expression index.

How would this compare to using an new keyword argument, like

create_table :users do |t|
  t.string :name
  t.index expression: 'lower(name)'
  t.index opclass: 'name varchar_pattern_ops'
end

@kamipo
Copy link
Member Author

kamipo commented Apr 19, 2016

Expressions and opclasses can be specified at the same time.

http://www.postgresql.org/docs/9.5/static/sql-createindex.html

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON table_name [ USING method ]
    ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
    [ WITH ( storage_parameter = value [, ... ] ) ]
    [ TABLESPACE tablespace_name ]
    [ WHERE predicate ]
create_table :users do |t|
  t.string :first_name
  t.string :last_name
  t.index -> { <<-EXPRESSIONS }
    first_name || last_name,
    upper(first_name) varchar_pattern_ops,
    lower(last_name) varchar_pattern_ops
  EXPRESSIONS
end

@jeremy
Copy link
Member

jeremy commented Apr 19, 2016

Gotcha. In that case, compare with e.g.

create_table :users do |t|
  t.string :first_name
  t.string :last_name
  t.index expression: <<-EXPRESSIONS
    first_name || last_name,
    upper(first_name) varchar_pattern_ops,
    lower(last_name) varchar_pattern_ops
  EXPRESSIONS
end

@kamipo
Copy link
Member Author

kamipo commented Apr 19, 2016

We already have using procs syntax for schema and attribute default expression.
#20005
https://github.com/rails/rails/blob/v5.0.0.beta3/activerecord/lib/active_record/attributes.rb#L83

Do we prefer new :expression option for indexes?

@jeremy
Copy link
Member

jeremy commented Apr 19, 2016

Good point.

Generally prefer keyword arguments for new constant-value arguments. Using a proc has worked well to bypass quoting or indicate SQL literals. So it makes sense to stick with them. This usage looks a lot more like passing a block to an index method, though. The other cases are keyword arg values, clear that they're 'special' values vs passing a proc/block.

Example:

    create_table :users do |t|
      t.string :name
      t.index 'lower(name) varchar_pattern_ops'
    end

Fixes rails#19090.
Fixes rails#21765.
Fixes rails#21819.
Fixes rails#24359.
@jeremy jeremy added this to the 5.1.0 milestone Apr 24, 2016
@kamipo
Copy link
Member Author

kamipo commented Apr 24, 2016

I changed implementation in This PR. This does not introduce new syntax now.
If column name that pass to add_index includes non word charactor, handles as raw string (regard as expressions).

create_table :users do |t|
  t.string :first_name
  t.string :last_name
  t.index <<-EXPRESSIONS
    first_name || last_name,
    upper(first_name) varchar_pattern_ops,
    lower(last_name) varchar_pattern_ops
  EXPRESSIONS
end

How about it?

@jeremy jeremy modified the milestones: 5.0.0, 5.1.0 Apr 24, 2016
@jeremy
Copy link
Member

jeremy commented Apr 24, 2016

Merged edc2b77 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants