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

SchemaDumper table_name_prefix and table_name_suffix with dollar sign support #30044

Closed
yahonda opened this issue Aug 2, 2017 · 4 comments
Closed

Comments

@yahonda
Copy link
Member

yahonda commented Aug 2, 2017

Summary

When table_name_prefix and table_name_suffix have the dollar sign "$",
SchemaDumper generates table name with table_name_prefix and table_name_suffix.
It should remove table_name_prefix and table_name_suffix.

Steps to reproduce

$ git clone http://github.com/yahonda/rep_schema_dumper_prefix_suffix_dollar_sign
$ cd rep_schema_dumper_prefix_suffix_dollar_sign
$ ruby rep_sqlite3.rb

Expected behavior

It should generate table name without table_name_prefix and table_name suffix. Just "posts".

Actual behavior

It generates "foo$posts$bar". with when table_name_prefix = "foo$" and ActiveRecord::Base.table_name_suffix = "$bar"

  • Formatted output below by replacing \n with actual new line:
Failure:
BugTest#test_schema_dump_with_table_name_prefix_and_suffix_with_dollar_sign [rep_sqlite3.rb:54]:
Expected /create_table "posts"/ to match "# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 0) do

  create_table \"foo$ar_internal_metadata$bar\", primary_key: \"key\", id: :string, force: :cascade do |t|
    t.string \"value\"
    t.datetime \"created_at\", null: false
    t.datetime \"updated_at\", null: false
    t.index [\"key\"], name: \"sqlite_autoindex_foo$ar_internal_metadata$bar_1\", unique: true
  end

  create_table \"foo$posts$bar\", force: :cascade do |t|
  end

end
".

System configuration

Rails version: master branch

Ruby version: 2.4.1

Additional information

I have found this behavior when I'm working for refactoring Oracle enhanced adapter
to use SchemaDumper#remove_prefix_and_suffix rsim/oracle-enhanced#1401

Oracle enhanced adapter allows (I mean it has test cases) table_name_prefix and table_name_suffix have the dollar sign.

From database point of view MySQL 5.7, PostgreSQL 9.6 and Oracle Database 12.1 allows table identifiers have dollar sign.

Permitted characters in unquoted identifiers:
ASCII: [0-9,a-z,A-Z$_] (basic Latin letters, digits 0-9, dollar, underscore)

SQL identifiers and key words must begin with a letter (a-z, but also letters with diacritical marks and non-Latin letters) or an underscore (_). Subsequent characters in an identifier or key word can be letters, underscores, digits (0-9), or dollar signs ($). Note that dollar signs are not allowed in identifiers according to the letter of the SQL standard, so their use might render applications less portable. The SQL standard will not define a key word that contains digits or starts or ends with an underscore, so identifiers of this form are safe against possible conflict with future extensions of the standard.

Nonquoted identifiers can contain only alphanumeric characters from your database character set and the underscore (_), dollar sign ($), and pound sign (#). Database links can also contain periods (.) and "at" signs (@).

Have not found if SQLite3 allows it or not.

@yahonda
Copy link
Member Author

yahonda commented Aug 2, 2017

Created a dirty workaround fix yahonda@2d674ac

@kamipo
Copy link
Member

kamipo commented Aug 2, 2017

Created a dirty workaround fix yahonda@2d674ac

It is better to use Regexp.escape:

prefix = Regexp.escape(@options[:table_name_prefix])
suffix = Regexp.escape(@options[:table_name_suffix])
table.sub(/\A(?:#{prefix})(.+)(?:#{suffix})\z/, "\\1")

@yahonda
Copy link
Member Author

yahonda commented Aug 2, 2017

Thanks as always. Regexp.escape looks better just escaping $ separately. Will create a pull request.

@yahonda
Copy link
Member Author

yahonda commented Aug 2, 2017

Opened #30048. Added .to_s to handle TypeError: no implicit conversion of nil into String when table_name_prefix or table_name_suffix is nil.

test/cases/migration/foreign_key_test.rb:          ActiveRecord::Base.table_name_prefix = nil
test/cases/migration/foreign_key_test.rb:          ActiveRecord::Base.table_name_suffix = nil
test/cases/migration/references_foreign_key_test.rb:          ActiveRecord::Base.table_name_prefix = nil
test/cases/migration/references_foreign_key_test.rb:          ActiveRecord::Base.table_name_suffix = nil
$

yahonda added a commit to yahonda/rails that referenced this issue Aug 4, 2017
MySQL 5.7 and PostgreSQL 9.6 allow table identifiers have the dollar sign.

* MySQL 5.7
https://dev.mysql.com/doc/refman/5.7/en/identifiers.html

> Permitted characters in unquoted identifiers:
>  ASCII: [0-9,a-z,A-Z$_] (basic Latin letters, digits 0-9, dollar, underscore)

* PostgreSQL 9.6
https://www.postgresql.org/docs/9.6/static/sql-syntax-lexical.html

> SQL identifiers and key words must begin with a letter (a-z, but also letters with diacritical marks and non-Latin letters) or an underscore (_). Subsequent characters in an identifier or key word can be letters, underscores, digits (0-9), or dollar signs ($). Note that dollar signs are not allowed in identifiers according to the letter of the SQL standard, so their use might render applications less portable. The SQL standard will not define a key word that contains digits or starts or ends with an underscore, so identifiers of this form are safe against possible conflict with future extensions of the standard.

Address rails#30044

[Yasuo Honda & Ryuta Kamizono]
yahonda added a commit to yahonda/oracle-enhanced that referenced this issue Aug 16, 2017
Since rails/rails#30048 there is no Oracle enhanced specific implementation anymore.
Tests are covered by `ActiveRecord::TestCase::SchemaDumperTest`

Refer rsim#1401 rails/rails#30044 rails/rails#30048
yahonda added a commit to yahonda/oracle-enhanced that referenced this issue Aug 16, 2017
Since rails/rails#30048 there is no Oracle enhanced specific implementation anymore.
Tests are covered by `ActiveRecord::TestCase::SchemaDumperTest`

Refer rsim#1401 rails/rails#30044 rails/rails#30048
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants