lib/pgslice.rb in pgslice-0.3.5 vs lib/pgslice.rb in pgslice-0.3.6
- old
+ new
@@ -110,11 +110,11 @@
abort "Usage: pgslice unprep <table>" if arguments.length != 1
abort "Table not found: #{intermediate_table}" unless table_exists?(intermediate_table)
queries = [
"DROP TABLE #{quote_ident(intermediate_table)} CASCADE;",
- "DROP FUNCTION IF EXISTS #{trigger_name}();"
+ "DROP FUNCTION IF EXISTS #{quote_ident(trigger_name)}();"
]
run_queries(queries)
end
def add_partitions
@@ -130,11 +130,11 @@
range = (-1 * past)..future
# ensure table has trigger
abort "No trigger on table: #{table}\nDid you mean to use --intermediate?" unless has_trigger?(trigger_name, table)
- index_defs = execute("SELECT pg_get_indexdef(indexrelid) FROM pg_index INNER JOIN pg_stat_user_indexes USING (indexrelid) WHERE relname = $1 AND schemaname = $2 AND indisprimary = 'f'", [original_table, schema]).map { |r| r["pg_get_indexdef"] }
+ index_defs = execute("SELECT pg_get_indexdef(indexrelid) FROM pg_index WHERE indrelid = #{regclass(schema, original_table)} AND indisprimary = 'f'").map { |r| r["pg_get_indexdef"] }
primary_key = self.primary_key(table)
queries = []
period, field, cast, needs_comment = settings_from_trigger(original_table, table)
@@ -161,20 +161,20 @@
SQL
queries << "ALTER TABLE #{quote_ident(partition_name)} ADD PRIMARY KEY (#{quote_ident(primary_key)});" if primary_key
index_defs.each do |index_def|
- queries << index_def.sub(" ON #{original_table} USING ", " ON #{partition_name} USING ").sub(/ INDEX .+ ON /, " INDEX ON ") + ";"
+ queries << index_def.sub(/ ON \S+ USING /, " ON #{quote_ident(partition_name)} USING ").sub(/ INDEX .+ ON /, " INDEX ON ") + ";"
end
end
# update trigger based on existing partitions
current_defs = []
future_defs = []
past_defs = []
name_format = self.name_format(period)
- existing_tables = self.existing_tables(like: "#{original_table}_%").select { |t| /\A#{Regexp.escape("#{original_table}_")}\d{6,8}\z/.match(t) }
+ existing_tables = existing_partitions(original_table)
existing_tables = (existing_tables + added_partitions).uniq.sort
existing_tables.each do |table|
day = DateTime.strptime(table.split("_").last, name_format)
partition_name = "#{original_table}_#{day.strftime(name_format(period))}"
@@ -234,11 +234,11 @@
period, field, cast, needs_comment = settings_from_trigger(table, dest_table)
if period
name_format = self.name_format(period)
- existing_tables = self.existing_tables(like: "#{table}_%").select { |t| /\A#{Regexp.escape("#{table}_")}\d{6,8}\z/.match(t) }.sort
+ existing_tables = existing_partitions(table)
if existing_tables.any?
starting_time = DateTime.strptime(existing_tables.first.split("_").last, name_format)
ending_time = advance_date(DateTime.strptime(existing_tables.last.split("_").last, name_format), period, 1)
end
end
@@ -313,11 +313,11 @@
"ALTER TABLE #{quote_ident(table)} RENAME TO #{quote_ident(retired_table)};",
"ALTER TABLE #{quote_ident(intermediate_table)} RENAME TO #{quote_ident(table)};"
]
self.sequences(table).each do |sequence|
- queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_name"])} OWNED BY #{table}.#{sequence["related_column"]};"
+ queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_name"])} OWNED BY #{quote_ident(table)}.#{quote_ident(sequence["related_column"])};"
end
queries.unshift("SET LOCAL lock_timeout = '#{options[:lock_timeout]}';") if server_version_num >= 90300
run_queries(queries)
@@ -337,11 +337,11 @@
"ALTER TABLE #{quote_ident(table)} RENAME TO #{quote_ident(intermediate_table)};",
"ALTER TABLE #{quote_ident(retired_table)} RENAME TO #{quote_ident(table)};"
]
self.sequences(table).each do |sequence|
- queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_name"])} OWNED BY #{table}.#{sequence["related_column"]};"
+ queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_name"])} OWNED BY #{quote_ident(table)}.#{quote_ident(sequence["related_column"])};"
end
run_queries(queries)
end
@@ -349,11 +349,11 @@
table = arguments.first
parent_table = options[:swapped] ? table : intermediate_name(table)
abort "Usage: pgslice analyze <table>" if arguments.length != 1
- existing_tables = self.existing_tables(like: "#{table}_%").select { |t| /\A#{Regexp.escape("#{table}_")}\d{6,8}\z/.match(t) }
+ existing_tables = existing_partitions(table)
analyze_list = existing_tables + [parent_table]
run_queries_without_transaction analyze_list.map { |t| "ANALYZE VERBOSE #{quote_ident(t)};" }
end
# arguments
@@ -462,10 +462,14 @@
def server_version_num
execute("SHOW server_version_num")[0]["server_version_num"].to_i
end
+ def existing_partitions(table)
+ existing_tables(like: "#{table}_%").select { |t| /\A#{Regexp.escape("#{table}_")}\d{6,8}\z/.match(t) }
+ end
+
def existing_tables(like:)
query = "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = $1 AND tablename LIKE $2"
execute(query, [schema, like]).map { |r| r["tablename"] }.sort
end
@@ -597,11 +601,15 @@
def quote_ident(value)
PG::Connection.quote_ident(value)
end
+ def regclass(schema, table)
+ "'#{quote_ident(schema)}.#{quote_ident(table)}'::regclass"
+ end
+
def fetch_trigger(trigger_name, table)
- execute("SELECT obj_description(oid, 'pg_trigger') AS comment FROM pg_trigger WHERE tgname = $1 AND EXISTS (SELECT 1 FROM pg_stat_user_tables WHERE relid = tgrelid AND relname = $2 AND schemaname = $3)", [trigger_name, table, schema])[0]
+ execute("SELECT obj_description(oid, 'pg_trigger') AS comment FROM pg_trigger WHERE tgname = $1 AND tgrelid = #{regclass(schema, table)}", [trigger_name])[0]
end
def settings_from_trigger(original_table, table)
trigger_name = self.trigger_name(original_table)