mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			96 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
 | 
						|
from typing import Any, Callable, Dict, List, Set, Text
 | 
						|
 | 
						|
from django.db import connection
 | 
						|
 | 
						|
from zerver.lib.management import ZulipBaseCommand
 | 
						|
 | 
						|
def create_index_if_not_exist(index_name: Text, table_name: Text,
 | 
						|
                              column_string: Text, where_clause: Text) -> None:
 | 
						|
    #
 | 
						|
    #  This function is somewhat similar to
 | 
						|
    #  zerver.lib.migrate.create_index_if_not_exist.
 | 
						|
    #
 | 
						|
    #  The other function gets used as part of Django migrations; this function
 | 
						|
    #  uses SQL that is not supported by Django migrations.
 | 
						|
    #
 | 
						|
    #  Creating concurrent indexes is kind of a pain with current versions
 | 
						|
    #  of Django/postgres, because you will get this error with seemingly
 | 
						|
    #  reasonable code:
 | 
						|
    #
 | 
						|
    #    CREATE INDEX CONCURRENTLY cannot be executed from a function or multi-command string
 | 
						|
    #
 | 
						|
    # For a lot more detail on this process, refer to the commit message
 | 
						|
    # that added this file to the repo.
 | 
						|
 | 
						|
    with connection.cursor() as cursor:
 | 
						|
        sql = '''
 | 
						|
            SELECT 1
 | 
						|
            FROM pg_class
 | 
						|
            where relname = %s
 | 
						|
            '''
 | 
						|
        cursor.execute(sql, [index_name])
 | 
						|
        rows = cursor.fetchall()
 | 
						|
        if len(rows) > 0:
 | 
						|
            print('Index %s already exists.' % (index_name,))
 | 
						|
            return
 | 
						|
 | 
						|
        print("Creating index %s." % (index_name,))
 | 
						|
        sql = '''
 | 
						|
            CREATE INDEX CONCURRENTLY
 | 
						|
            %s
 | 
						|
            ON %s (%s)
 | 
						|
            %s;
 | 
						|
            ''' % (index_name, table_name, column_string, where_clause)
 | 
						|
        cursor.execute(sql)
 | 
						|
        print('Finished creating %s.' % (index_name,))
 | 
						|
 | 
						|
 | 
						|
def create_indexes() -> None:
 | 
						|
 | 
						|
    # copied from 0082
 | 
						|
    create_index_if_not_exist(
 | 
						|
        index_name='zerver_usermessage_starred_message_id',
 | 
						|
        table_name='zerver_usermessage',
 | 
						|
        column_string='user_profile_id, message_id',
 | 
						|
        where_clause='WHERE (flags & 2) != 0',
 | 
						|
    )
 | 
						|
 | 
						|
    # copied from 0083
 | 
						|
    create_index_if_not_exist(
 | 
						|
        index_name='zerver_usermessage_mentioned_message_id',
 | 
						|
        table_name='zerver_usermessage',
 | 
						|
        column_string='user_profile_id, message_id',
 | 
						|
        where_clause='WHERE (flags & 8) != 0',
 | 
						|
    )
 | 
						|
 | 
						|
    # copied from 0095
 | 
						|
    create_index_if_not_exist(
 | 
						|
        index_name='zerver_usermessage_unread_message_id',
 | 
						|
        table_name='zerver_usermessage',
 | 
						|
        column_string='user_profile_id, message_id',
 | 
						|
        where_clause='WHERE (flags & 1) = 0',
 | 
						|
    )
 | 
						|
 | 
						|
    # copied from 0098
 | 
						|
    create_index_if_not_exist(
 | 
						|
        index_name='zerver_usermessage_has_alert_word_message_id',
 | 
						|
        table_name='zerver_usermessage',
 | 
						|
        column_string='user_profile_id, message_id',
 | 
						|
        where_clause='WHERE (flags & 512) != 0',
 | 
						|
    )
 | 
						|
 | 
						|
    # copied from 0099
 | 
						|
    create_index_if_not_exist(
 | 
						|
        index_name='zerver_usermessage_wildcard_mentioned_message_id',
 | 
						|
        table_name='zerver_usermessage',
 | 
						|
        column_string='user_profile_id, message_id',
 | 
						|
        where_clause='WHERE (flags & 8) != 0 OR (flags & 16) != 0',
 | 
						|
    )
 | 
						|
 | 
						|
class Command(ZulipBaseCommand):
 | 
						|
    help = """Create concurrent indexes for large tables."""
 | 
						|
 | 
						|
    def handle(self, *args: Any, **options: str) -> None:
 | 
						|
        create_indexes()
 |