text:
import React, { Component, PropTypes } from 'react';
import ButtonAdd from 'common/button/ButtonAdd';
import AddButton from 'common/button/AddButton';
import { Comment2 } from 'common/icons';
import subscribeValidation from 'common/subscribeValidation';

import IconHeadingBlock from '../../common/IconHeadingBlock';
import Title from '../../common/Title';
import Sections from '../../common/Sections';
import InterviewQas from './InterviewQas';
import InterviewSensitiveQuestions from './InterviewSensitiveQuestions';

import shareStyles from '../../common/share.module.css';

import {
  title as titleValidator,
  sections as sectionsValidator,
} from '../formCheck';

import {
  interviewSectionSubtitleOptions,
} from '../../common/optionMap';

import { TITLE, SECTIONS } from '../../../../constants/formElements';

const TitleWithValidation = subscribeValidation(
  Title,
  props => props.validator(props.title),
  TITLE,
);

const SectionsWithValidation = subscribeValidation(
  Sections,
  props => props.validator(props.sections),
  SECTIONS,
);

class InterviewExperience extends Component {
  render() {
    const {
      handleState,
      title,
      sections,
      appendSection,
      removeSection,
      editSection,
      interviewQas,
      appendQa,
      removeQa,
      editQa,
      interviewSensitiveQuestions,
      submitted,
      changeValidationStatus,
    } = this.props;
    return (
      <IconHeadingBlock heading="面試經驗" Icon={Comment2} marginTop>
        <div
          style={{
            marginBottom: '50px',
          }}
        >
          <TitleWithValidation
            title={title}
            onChange={handleState('title')}
            placeholder="OO 股份有限公司面試經驗分享"
            validator={titleValidator}
            submitted={submitted}
            changeValidationStatus={changeValidationStatus}
          />
        </div>
        <div
          style={{
            position: 'relative',
            marginBottom: '80px',
          }}
        >
          <SectionsWithValidation
            sections={sections}
            removeSection={removeSection}
            editSection={editSection}
            validator={sectionsValidator}
            submitted={submitted}
            changeValidationStatus={changeValidationStatus}
          />
          <div
            className={shareStyles.button__add}
          >
            <ButtonAdd
              options={interviewSectionSubtitleOptions}
              custimizedValues={[interviewSectionSubtitleOptions[0].value]}
              disabledValues={sections.map(section => section.subtitle)}
              appendBlock={appendSection}
            />
          </div>
        </div>
        <hr
          style={{
            border: '1px solid #E7E7E7',
            marginBottom: '35px',
          }}
        />
        <div
          style={{
            position: 'relative',
            marginBottom: '80px',
          }}
        >
          <InterviewQas
            interviewQas={interviewQas}
            editQa={editQa}
            removeQa={removeQa}
          />
          <div
            className={shareStyles.button__add}
          >
            <AddButton
              onClick={() => appendQa()}
              addQa
            />
          </div>
        </div>
        <hr
          style={{
            border: '1px solid #E7E7E7',
            marginBottom: '35px',
          }}
        />
        <div>
          <InterviewSensitiveQuestions
            interviewSensitiveQuestions={interviewSensitiveQuestions}
            onChange={handleState('interviewSensitiveQuestions')}
          />
        </div>
      </IconHeadingBlock>
    );
  }
}

InterviewExperience.propTypes = {
  handleState: PropTypes.func,
  title: PropTypes.string,
  sections: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.number,
    subtitle: PropTypes.string,
    placeholder: PropTypes.string,
    content: PropTypes.string,
  })),
  appendSection: PropTypes.func,
  removeSection: PropTypes.func,
  editSection: PropTypes.func,
  interviewQas: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.number,
    subtitle: PropTypes.string,
    content: PropTypes.string,
  })),
  appendQa: PropTypes.func,
  removeQa: PropTypes.func,
  editQa: PropTypes.func,
  interviewSensitiveQuestions: PropTypes.arrayOf(
    PropTypes.string,
  ),
  submitted: PropTypes.bool,
  changeValidationStatus: PropTypes.func,
};

export default InterviewExperience;


text:
SRCC is a Java API on top of Jedis 2.6 which distributes keys between Redis 2.8 hosts running in stand alone mode. It allows Redis 2.8 servers which doesn't support clustering to horizontally scale.

## How to Use It?
1> Start Redis 2.8 nodes in stand alone mode (You can use configuration file @ srcc/release/redisNonCluster.conf).

2> Enter the Redis Hosts and ports details in srcc_en_US.properties which is found at src/main/resources and Build the project.

3> Simply consome SRCC using a Java code like:

```java
InMemoryDSConnection inMemCon = SRCCSingleton.getInstance();//Get Instance and initialize cluster connection
inMemCon.putInCache("TestKey", "TestValue");//put a value in cluster
System.out.println("TestKey Set");//
System.out.println("Retrieved from cache: "+inMemCon.getFromCache("TestKey"));//get the value back from the cluster
```

## License
Open source under Apache License Version 2.0

redpajama_set_name: RedPajamaGithub


text:
package org.apereo.cas.adaptors.u2f.web.flow;

import org.apereo.cas.authentication.CoreAuthenticationTestUtils;
import org.apereo.cas.util.MockServletContext;
import org.apereo.cas.web.flow.CasWebflowConstants;
import org.apereo.cas.web.support.WebUtils;

import lombok.val;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.context.servlet.ServletExternalContext;
import org.springframework.webflow.execution.RequestContextHolder;
import org.springframework.webflow.test.MockRequestContext;

import java.util.UUID;

import static org.junit.jupiter.api.Assertions.*;

/**
 * This is {@link U2FAccountCheckRegistrationActionTests}.
 *
 * @author Misagh Moayyed
 * @since 6.2.0
 */
@SpringBootTest(classes = {
    BaseU2FWebflowActionTests.U2FTestConfiguration.class,
    BaseU2FWebflowActionTests.SharedTestConfiguration.class
})
@Tag("WebflowMfaActions")
public class U2FAccountCheckRegistrationActionTests extends BaseU2FWebflowActionTests {
    @Test
    public void verifyOperation() throws Exception {
        val id = UUID.randomUUID().toString();
        val context = new MockRequestContext();
        val request = new MockHttpServletRequest();

        val response = new MockHttpServletResponse();
        WebUtils.putAuthentication(CoreAuthenticationTestUtils.getAuthentication(id), context);
        context.setExternalContext(new ServletExternalContext(new MockServletContext(), request, response));
        WebUtils.putMultifactorAuthenticationProviderIdIntoFlowScope(context, u2fMultifactorAuthenticationProvider);
        RequestContextHolder.setRequestContext(context);
        ExternalContextHolder.setExternalContext(context.getExternalContext());
        assertEquals(CasWebflowConstants.TRANSITION_ID_REGISTER, u2fCheckAccountRegistrationAction.execute(context).getId());
    }
}


text:
#include "com/centreon/misc/argument.hh"
#include <iostream>

using namespace com::centreon::misc;

/**
 *  Default constructor.
 *
 *  @param[in] long_name  Argument's long name.
 *  @param[in] name       Argument's name.
 *  @param[in] has_value  Argument need a value.
 *  @param[in] is_set     Argument is set by default.
 *  @param[in] value      The default value.
 */
argument::argument(std::string const& long_name,
                   char name,
                   std::string const& description,
                   bool has_value,
                   bool is_set,
                   std::string const& value)
    : _description(description),
      _is_set(is_set),
      _has_value(has_value),
      _long_name(long_name),
      _name(name),
      _value(value) {}

/**
 *  Default copy constructor.
 *
 *  @param[in] right  The object to copy.
 */
argument::argument(argument const& right) {
  _internal_copy(right);
}

/**
 *  Default destructor.
 */
argument::~argument() throw() {}

/**
 *  Default copy operator.
 *
 *  @param[in] right  The object to copy.
 *
 *  @return This object.
 */
argument& argument::operator=(argument const& right) {
  return (_internal_copy(right));
}

/**
 *  Equal operator.
 *
 *  @param[in] right The object to compare.
 *
 *  @return Tue if objects are equal, otherwise false.
 */
bool argument::operator==(argument const& right) const throw() {
  return (_name == right._name && _long_name == right._long_name &&
          _value == right._value && _is_set == right._is_set &&
          _has_value == right._has_value && _description == right._description);
}

/**
 *  Not equal operator.
 *
 *  @param[in] right The object to compare.
 *
 *  @return True if objects are different, otherwise false.
 */
bool argument::operator!=(argument const& right) const throw() {
  return (!operator==(right));
}

/**
 *  Get the argument description.
 *
 *  @return The description.
 */
std::string const& argument::get_description() const throw() {
  return (_description);
}

/**
 *  Get if argument is set.
 *
 *  @return True if argument is set.
 */
bool argument::get_is_set() const throw() {
  return (_is_set);
}

/**
 *  Get if argument need to has value.
 *
 *  @return True if argument need a value, otherwise false.
 */
bool argument::get_has_value() const throw() {
  return (_has_value);
}

/**
 *  Get the long name of the argument.
 *
 *  @return The long name.
 */
std::string const& argument::get_long_name() const throw() {
  return (_long_name);
}

/**
 *  Get the name of the argument.
 *
 *  @return The name.
 */
char argument::get_name() const throw() {
  return (_name);
}

/**
 *  Get the value.
 *
 *  @return The value.
 */
std::string const& argument::get_value() const throw() {
  return (_value);
}

/**
 *  Set the argument description.
 *
 *  @param[in] description  The description.
 */
void argument::set_description(std::string const& description) {
  _description = description;
}

/**
 *  Set is the argument is set.
 *
 *  @param[in] val  True if the argument is set.
 */
void argument::set_is_set(bool val) throw() {
  _is_set = val;
}

/**
 *  Set is the argument need a value.
 *
 *  @param[in] val  True if the argument need a value.
 */
void argument::set_has_value(bool val) throw() {
  _has_value = val;
}

/**
 *  Set the long name of the argument.
 *
 *  @param[in] long_name  The long name.
 */
void argument::set_long_name(std::string const& long_name) {
  _long_name = long_name;
}

/**
 *  Set the name of the argument.
 *
 *  @param[in] name  The name.
 */
void argument::set_name(char name) {
  _name = name;
}

/**
 *  Set the value of the argument.
 *
 *  @param[in] value  The value.
 */
void argument::set_value(std::string const& value) {
  _value = value;
}

/**
 *  Internal copy.
 *
 *  @param[in] right  The object to copy.
 *
 *  @return This object.
 */
argument& argument::_internal_copy(argument const& right) {
  if (this != &right) {
    _description = right._description;
    _is_set = right._is_set;
    _has_value = right._has_value;
    _long_name = right._long_name;
    _name = right._name;
    _value = right._value;
  }
  return (*this);
}


text:
.class Lcom/android/server/BatteryService$15;
.super Ljava/lang/Object;
.source "BatteryService.java"

# interfaces
.implements Ljava/lang/Runnable;

# annotations
.annotation system Ldalvik/annotation/EnclosingMethod;
    value = Lcom/android/server/BatteryService;->processValuesLocked(Z)V
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = null
.end annotation

# instance fields
.field final synthetic this$0:Lcom/android/server/BatteryService;

# direct methods
.method constructor <init>(Lcom/android/server/BatteryService;)V
    .locals 0

    iput-object p1, p0, Lcom/android/server/BatteryService$15;->this$0:Lcom/android/server/BatteryService;

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

# virtual methods
.method public run()V
    .locals 4

    new-instance v1, Landroid/content/Intent;

    const-string/jumbo v2, "android.intent.action.ACTION_POWER_DISCONNECTED"

    invoke-direct {v1, v2}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V

    const/high16 v2, 0x4000000

    invoke-virtual {v1, v2}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;

    iget-object v2, p0, Lcom/android/server/BatteryService$15;->this$0:Lcom/android/server/BatteryService;

    invoke-static {v2}, Lcom/android/server/BatteryService;->-get10(Lcom/android/server/BatteryService;)Landroid/content/Context;

    move-result-object v2

    sget-object v3, Landroid/os/UserHandle;->ALL:Landroid/os/UserHandle;

    invoke-virtual {v2, v1, v3}, Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

    invoke-static {}, Lcom/samsung/android/feature/SemCscFeature;->getInstance()Lcom/samsung/android/feature/SemCscFeature;

    move-result-object v2

    const-string/jumbo v3, "CscFeature_Common_SupportHuxAvs"

    invoke-virtual {v2, v3}, Lcom/samsung/android/feature/SemCscFeature;->getBoolean(Ljava/lang/String;)Z

    move-result v2

    if-eqz v2, :cond_0

    invoke-virtual {v1}, Landroid/content/Intent;->clone()Ljava/lang/Object;

    move-result-object v0

    check-cast v0, Landroid/content/Intent;

    const-string/jumbo v2, "com.verizon.mips.services"

    invoke-virtual {v0, v2}, Landroid/content/Intent;->setPackage(Ljava/lang/String;)Landroid/content/Intent;

    iget-object v2, p0, Lcom/android/server/BatteryService$15;->this$0:Lcom/android/server/BatteryService;

    invoke-static {v2}, Lcom/android/server/BatteryService;->-get10(Lcom/android/server/BatteryService;)Landroid/content/Context;

    move-result-object v2

    sget-object v3, Landroid/os/UserHandle;->ALL:Landroid/os/UserHandle;

    invoke-virtual {v2, v0, v3}, Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

    :cond_0
    return-void
.end method


text:
module GitHub where
import GitHub.Internal


text:
import {
  TEXT,
  LIST,
  DATE,
  TIME,
  DATETIME,
  getTransformType,
} from "@app/constants/DataTypes";

export default function mapConvertDataType(form) {
  const {
    columnName,
    newFieldName,
    dropSourceField,
    columnType,
    toType,
    ...data
  } = form;
  const transformType = getTransformType(data, columnType, toType);

  let fieldTransformation = {
    ...data,
    type: transformType,
  };
  // hacky tweaking of params for different transform types

  if (columnType === LIST && toType === TEXT) {
    delete fieldTransformation.format;
  }

  if (fieldTransformation.type === "SimpleConvertToType") {
    fieldTransformation.dataType = toType;
  } else {
    if ([DATE, TIME, DATETIME].indexOf(toType) !== -1) {
      fieldTransformation.desiredType = toType;
    }

    if ([DATE, TIME, DATETIME].indexOf(columnType) !== -1 && toType !== TEXT) {
      fieldTransformation.convertType = columnType;
      fieldTransformation.desiredType = toType;
    }

    if ([DATE, TIME, DATETIME].indexOf(columnType) !== -1 && toType === TEXT) {
      fieldTransformation.convertType = columnType;
    }
  }

  //remove other arguments for JSON
  if (fieldTransformation.type === "ConvertToJSON") {
    fieldTransformation = { type: "ConvertToJSON" };
  }

  return {
    type: "field",
    sourceColumnName: columnName,
    newColumnName: newFieldName,
    dropSourceColumn: dropSourceField,
    fieldTransformation,
  };
}


text:
<?php
namespace Mcrypt;

class String
{
    const zeroPadding  = 0;
    const pkcs5Padding = 1;
    const pkcs7Padding = 2;

    public static function padding($string, $length, $char)
    {
        $strLength = strlen($string);
        if ($strLength > $length) {
            return substr($string, 0, $length);
        } else if($strLength < $length) {
            return str_pad($string, $length, $char);
        }
        return $string;
    }

    /**
    * 使用0补齐字符串
    * @param string $string
    * @param int $blockSize
    * @return string
    */
    public static function zeroPadding($string, $blockSize)
    {
        $strLength = strlen($string);
        $padding = $blockSize - ($strLength % $blockSize);
        return self::padding($string, $strLength + $padding, chr(0));
    }

    /**
    * 使用pkcs5Padding补齐字符串,块固定是8位
    * @param string $string
    * @return string
    */
    public static function pkcs5Padding($string)
    {
        $strLength = strlen($string);
        $padding = 8 - ($strLength % 8);
        return self::padding($string, $strLength + $padding, chr($padding));
    }

    /**
    * 删除pkcs5Padding补齐字符串,块固定是8位
    * @param string $string
    * @return string
    */
    public static function unPkcs5Padding($string)
    {
        $padding = ord($string{strlen($string) - 1});
        return substr($string, 0, -1 * $padding);
    }

    /**
    * 使用pkcs7Padding补齐字符串,块固定是8位
    * @param string $string
    * @param int $blockSize
    * @return string
    */
    public static function pkcs7Padding($string, $blockSize)
    {
        $strLength = strlen($string);
        $padding = $blockSize - ($strLength % $blockSize);
        return self::padding($string, $strLength + $padding, chr($padding));
    }

    /**
    * 删除pkcs7Padding补齐字符串
    * @param string $string
    * @return string
    */
    public static function unPkcs7Padding($string)
    {
        $padding = ord($string{strlen($string) - 1});
        return substr($string, 0, -1 * $padding);
    }
}


text:
/**
 * @typedef {import('nlcst').Paragraph} Paragraph
 */

import {toString} from 'nlcst-to-string'
import {modifyChildren} from 'unist-util-modify-children'

// Merge a sentence into its previous sentence, when the sentence starts with a
// comma.
export const mergeAffixExceptions = modifyChildren(
  /**
   * @type {import('unist-util-modify-children').Modifier<Paragraph>}
   */
  function (child, index, parent) {
    const previous = parent.children[index - 1]

    if (
      previous &&
      'children' in previous &&
      'children' in child &&
      child.children.length > 0
    ) {
      let position = -1

      while (child.children[++position]) {
        const node = child.children[position]

        if (node.type === 'WordNode') {
          return
        }

        if (node.type === 'SymbolNode' || node.type === 'PunctuationNode') {
          const value = toString(node)

          if (value !== ',' && value !== ';') {
            return
          }

          previous.children.push(...child.children)

          // Update position.
          if (previous.position && child.position) {
            previous.position.end = child.position.end
          }

          parent.children.splice(index, 1)

          // Next, iterate over the node *now* at the current position.
          return index
        }
      }
    }
  }
)


text:
package com.eas.designer.application.query.editing.riddle;

import java.util.List;
import net.sf.jsqlparser.expression.AllComparisonExpression;
import net.sf.jsqlparser.expression.AnyComparisonExpression;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.CaseExpression;
import net.sf.jsqlparser.expression.DateValue;
import net.sf.jsqlparser.expression.DoubleValue;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.expression.InverseExpression;
import net.sf.jsqlparser.expression.JdbcParameter;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.NamedParameter;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.TimeValue;
import net.sf.jsqlparser.expression.TimestampValue;
import net.sf.jsqlparser.expression.WhenClause;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.Between;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import net.sf.jsqlparser.expression.operators.relational.Matches;
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.Connect;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SubSelect;

/**
 * A class to de-parse (that is, tranform from JSqlParser hierarchy into a
 * string) an {@link net.sf.jsqlparser.expression.Expression}
 */
public class ExpressionRiddler implements ExpressionVisitor, ItemsListVisitor {

    protected SelectVisitor selectVisitor;
    protected RiddleTask riddleTask;

    /**
     * @param selectVisitor a SelectVisitor to de-parse SubSelects. It has to
     * share the same
 StringBuilder as this object in order to work, as:

     *
     * FinderTask myTask = new FinderTask();
     * MySelectRiddler selectRiddler = new  MySelectRiddler();
     * ExpressionRiddler expressionDeParser = new ExpressionRiddler(selectRiddler, myTask);
     *
     *

     * @param buffer the buffer that will be filled with the expression
     */
    public ExpressionRiddler(SelectVisitor selectVisitor, RiddleTask riddleTask) {
        this.selectVisitor = selectVisitor;
        this.riddleTask = riddleTask;
    }

    public RiddleTask getRiddleTask() {
        return riddleTask;
    }

    public Expression checkAndRepairTopLevelBinaryExpression(BinaryExpression binaryExpression) {
        if (!riddleTask.markedAsDeleted(binaryExpression)) {
            boolean leftDeleted = riddleTask.markedAsDeleted(binaryExpression.getLeftExpression());
            boolean rightDeleted = riddleTask.markedAsDeleted(binaryExpression.getRightExpression());
            if (leftDeleted || rightDeleted) {
                riddleTask.markAsDeleted(binaryExpression);
                if (leftDeleted && !rightDeleted) {
                    return binaryExpression.getRightExpression();
                } else if (rightDeleted && !leftDeleted) {
                    return binaryExpression.getLeftExpression();
                }
            } else {
                return binaryExpression;
            }
        }
        return null;
    }

    protected void checkAndRepairBinaryExpression(BinaryExpression binaryExpression) {
        // Здесь надо проверить, а не побитые ли у этого оператора дочерние выражения
        // и, если это так, попробовать восстановить этот оператор с помощью одной из
        // частей побитого дочернего выражения.
        // Если же не осталось ни одной части, то удалить его совсем.
        if (!riddleTask.markedAsDeleted(binaryExpression.getLeftExpression())
                && !riddleTask.markedAsDeleted(binaryExpression.getRightExpression())) {
            Expression toExamine = binaryExpression.getLeftExpression();
            if (toExamine instanceof BinaryExpression) {
                BinaryExpression bToExamine = (BinaryExpression) toExamine;
                boolean leftDeleted = riddleTask.markedAsDeleted(bToExamine.getLeftExpression());
                boolean rightDeleted = riddleTask.markedAsDeleted(bToExamine.getRightExpression());
                if (leftDeleted || rightDeleted) {
                    riddleTask.markAsDeleted(bToExamine);
                    if (leftDeleted && !rightDeleted) {
                        binaryExpression.setLeftExpression(bToExamine.getRightExpression());
                    } else if (rightDeleted && !leftDeleted) {
                        binaryExpression.setLeftExpression(bToExamine.getLeftExpression());
                    }
                }
            }
            toExamine = binaryExpression.getRightExpression();
            if (toExamine instanceof BinaryExpression) {
                BinaryExpression bToExamine = (BinaryExpression) toExamine;
                boolean leftDeleted = riddleTask.markedAsDeleted(bToExamine.getLeftExpression());
                boolean rightDeleted = riddleTask.markedAsDeleted(bToExamine.getRightExpression());
                if (leftDeleted || rightDeleted) {
                    riddleTask.markAsDeleted(bToExamine);
                    if (leftDeleted && !rightDeleted) {
                        binaryExpression.setRightExpression(bToExamine.getRightExpression());
                    } else if (rightDeleted && !leftDeleted) {
                        binaryExpression.setRightExpression(bToExamine.getLeftExpression());
                    }
                }
            }
        }
    }

    @Override
    public void visit(Addition addition) {
        visitBinaryExpression(addition);
    }

    @Override
    public void visit(AndExpression andExpression) {
        visitBinaryExpression(andExpression);
    }

    @Override
    public void visit(Between between) {
        between.getLeftExpression().accept(this);
        between.getBetweenExpressionStart().accept(this);
        between.getBetweenExpressionEnd().accept(this);

        // left expression
        if (between.getLeftExpression() instanceof BinaryExpression) {
            between.setLeftExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) between.getLeftExpression()));
        } else if (riddleTask.needToDelete(between.getLeftExpression()) || riddleTask.markedAsDeleted(between.getLeftExpression())) {
            riddleTask.markAsDeleted(between.getLeftExpression());
            between.setLeftExpression(null);
        }
        // start expression
        if (between.getBetweenExpressionStart() instanceof BinaryExpression) {
            between.setBetweenExpressionStart(checkAndRepairTopLevelBinaryExpression((BinaryExpression) between.getBetweenExpressionStart()));
        } else if (riddleTask.needToDelete(between.getBetweenExpressionStart()) || riddleTask.markedAsDeleted(between.getBetweenExpressionStart())) {
            riddleTask.markAsDeleted(between.getBetweenExpressionStart());
            between.setBetweenExpressionStart(null);
        }
        // end expression
        if (between.getBetweenExpressionEnd() instanceof BinaryExpression) {
            between.setBetweenExpressionEnd(checkAndRepairTopLevelBinaryExpression((BinaryExpression) between.getBetweenExpressionEnd()));
        } else if (riddleTask.needToDelete(between.getBetweenExpressionEnd()) || riddleTask.markedAsDeleted(between.getBetweenExpressionEnd())) {
            riddleTask.markAsDeleted(between.getBetweenExpressionEnd());
            between.setBetweenExpressionEnd(null);
        }

        if (between.getLeftExpression() == null
                || between.getBetweenExpressionStart() == null
                || between.getBetweenExpressionEnd() == null) {
            riddleTask.markAsDeleted(between);
        }
    }

    @Override
    public void visit(Division division) {
        visitBinaryExpression(division);
    }

    @Override
    public void visit(DoubleValue doubleValue) {
    }

    @Override
    public void visit(EqualsTo equalsTo) {
        visitBinaryExpression(equalsTo);
    }

    @Override
    public void visit(GreaterThan greaterThan) {
        visitBinaryExpression(greaterThan);
    }

    @Override
    public void visit(GreaterThanEquals greaterThanEquals) {
        visitBinaryExpression(greaterThanEquals);
    }

    @Override
    public void visit(InExpression inExpression) {
        inExpression.getLeftExpression().accept(this);
        inExpression.getItemsList().accept(this);

        if (inExpression.getLeftExpression() instanceof BinaryExpression) {
            inExpression.setLeftExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) inExpression.getLeftExpression()));
        } else if (riddleTask.needToDelete(inExpression.getLeftExpression()) || riddleTask.markedAsDeleted(inExpression.getLeftExpression())) {
            riddleTask.markAsDeleted(inExpression.getLeftExpression());
            inExpression.setLeftExpression(null);
        }

        // check validity
        if (inExpression.getLeftExpression() == null) {
            riddleTask.markAsDeleted(inExpression);
        }
        if (inExpression.getItemsList() instanceof ExpressionList) {
            ExpressionList el = (ExpressionList) inExpression.getItemsList();
            if (el.getExpressions().isEmpty()) {
                riddleTask.markAsDeleted(inExpression);
            }
        }
    }

    @Override
    public void visit(InverseExpression inverseExpression) {
        inverseExpression.getExpression().accept(this);
        if (inverseExpression.getExpression() instanceof BinaryExpression) {
            inverseExpression.setExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) inverseExpression.getExpression()));
        } else if (riddleTask.needToDelete(inverseExpression.getExpression()) || riddleTask.markedAsDeleted(inverseExpression.getExpression())) {
            riddleTask.markAsDeleted(inverseExpression.getExpression());
            inverseExpression.setExpression(null);
        }
        if (inverseExpression.getExpression() == null || riddleTask.needToDelete(inverseExpression)) {
            riddleTask.markAsDeleted(inverseExpression);
        }
    }

    @Override
    public void visit(IsNullExpression isNullExpression) {
        isNullExpression.getLeftExpression().accept(this);
        if (isNullExpression.getLeftExpression() instanceof BinaryExpression) {
            isNullExpression.setLeftExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) isNullExpression.getLeftExpression()));
        } else if (riddleTask.needToDelete(isNullExpression.getLeftExpression()) || riddleTask.markedAsDeleted(isNullExpression.getLeftExpression())) {
            riddleTask.markAsDeleted(isNullExpression.getLeftExpression());
            isNullExpression.setLeftExpression(null);
        }
        if (isNullExpression.getLeftExpression() == null) {
            riddleTask.markAsDeleted(isNullExpression);
        }
    }

    @Override
    public void visit(JdbcParameter jdbcParameter) {
    }

    @Override
    public void visit(LikeExpression likeExpression) {
        visitBinaryExpression(likeExpression);
    }

    @Override
    public void visit(ExistsExpression existsExpression) {
        existsExpression.getRightExpression().accept(this);
        if (existsExpression.getRightExpression() instanceof BinaryExpression) {
            existsExpression.setRightExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) existsExpression.getRightExpression()));
        } else if (riddleTask.needToDelete(existsExpression.getRightExpression()) || riddleTask.markedAsDeleted(existsExpression.getRightExpression())) {
            riddleTask.markAsDeleted(existsExpression.getRightExpression());
            existsExpression.setRightExpression(null);
        }
        if (existsExpression.getRightExpression() == null) {
            riddleTask.markAsDeleted(existsExpression);
        }
    }

    @Override
    public void visit(LongValue longValue) {
    }

    @Override
    public void visit(MinorThan minorThan) {
        visitBinaryExpression(minorThan);

    }

    @Override
    public void visit(MinorThanEquals minorThanEquals) {
        visitBinaryExpression(minorThanEquals);

    }

    @Override
    public void visit(Multiplication multiplication) {
        visitBinaryExpression(multiplication);
    }

    @Override
    public void visit(NotEqualsTo notEqualsTo) {
        visitBinaryExpression(notEqualsTo);
    }

    @Override
    public void visit(NullValue nullValue) {
    }

    @Override
    public void visit(OrExpression orExpression) {
        visitBinaryExpression(orExpression);
    }

    @Override
    public void visit(Parenthesis parenthesis) {
        parenthesis.getExpression().accept(this);
        if (parenthesis.getExpression() instanceof BinaryExpression) {
            parenthesis.setExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) parenthesis.getExpression()));
        } else if (riddleTask.needToDelete(parenthesis.getExpression()) || riddleTask.markedAsDeleted(parenthesis.getExpression())) {
            riddleTask.markAsDeleted(parenthesis.getExpression());
            parenthesis.setExpression(null);
        }
        if (parenthesis.getExpression() == null || riddleTask.needToDelete(parenthesis)) {
            riddleTask.markAsDeleted(parenthesis);
        }
    }

    @Override
    public void visit(StringValue stringValue) {
    }

    @Override
    public void visit(Subtraction subtraction) {
        visitBinaryExpression(subtraction);
    }

    private void visitBinaryExpression(BinaryExpression binaryExpression) {
        binaryExpression.getLeftExpression().accept(this);
        binaryExpression.getRightExpression().accept(this);
        if (riddleTask.needToDelete(binaryExpression)) {
            riddleTask.markAsDeleted(binaryExpression);
        } else {
            checkAndRepairBinaryExpression(binaryExpression);
        }
    }

    @Override
    public void visit(Column tableColumn) {
        if (riddleTask.needToDelete(tableColumn)) {
            riddleTask.markAsDeleted(tableColumn);
        }
    }

    @Override
    public void visit(NamedParameter namedParameter) {
        if (riddleTask.needToDelete(namedParameter)) {
            riddleTask.markAsDeleted(namedParameter);
        }
    }

    @Override
    public void visit(SubSelect subSelect) {
        subSelect.getSelectBody().accept(selectVisitor);
    }

    @Override
    public void visit(Function function) {
        if (!function.isAllColumns() && function.getParameters() != null) {
            visit(function.getParameters());
        }
    }

    @Override
    public void visit(ExpressionList expressionList) {
        for (int i = expressionList.getExpressions().size() - 1; i >= 0; i--) {
            Expression expression = expressionList.getExpressions().get(i);
            expression.accept(this);
            if (expression instanceof BinaryExpression) {
                expression = checkAndRepairTopLevelBinaryExpression((BinaryExpression) expression);
                if (expression != null) {
                    expressionList.getExpressions().set(i, expression);
                } else {
                    expressionList.getExpressions().remove(i);
                }
            } else if (riddleTask.needToDelete(expression) || riddleTask.markedAsDeleted(expression)) {
                riddleTask.markAsDeleted(expression);
                expressionList.getExpressions().remove(i);
            }
        }
    }

    public SelectVisitor getSelectVisitor() {
        return selectVisitor;
    }

    public void setSelectVisitor(SelectVisitor visitor) {
        selectVisitor = visitor;
    }

    @Override
    public void visit(DateValue dateValue) {
    }

    @Override
    public void visit(TimestampValue timestampValue) {
    }

    @Override
    public void visit(TimeValue timeValue) {
    }

    @Override
    public void visit(CaseExpression caseExpression) {
        Expression switchExp = caseExpression.getSwitchExpression();
        if (switchExp != null) {
            switchExp.accept(this);
            if (switchExp instanceof BinaryExpression) {
                caseExpression.setSwitchExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) switchExp));
            } else if (riddleTask.needToDelete(switchExp) || riddleTask.markedAsDeleted(switchExp)) {
                riddleTask.markAsDeleted(switchExp);
                caseExpression.setSwitchExpression(null);
            }
        }

        List<WhenClause> clauses = caseExpression.getWhenClauses();
        for (int i = clauses.size() - 1; i >= 0; i--) {
            WhenClause exp = clauses.get(i);
            visit(exp);
            if (exp.getThenExpression() == null || exp.getWhenExpression() == null) {
                clauses.remove(i);
            }
        }

        Expression elseExp = caseExpression.getElseExpression();
        if (elseExp != null) {
            elseExp.accept(this);

            if (elseExp instanceof BinaryExpression) {
                caseExpression.setElseExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) elseExp));
            } else if (riddleTask.needToDelete(elseExp) || riddleTask.markedAsDeleted(elseExp)) {
                riddleTask.markAsDeleted(elseExp);
                caseExpression.setElseExpression(null);
            }
        }

        if (caseExpression.getSwitchExpression() == null || caseExpression.getWhenClauses().isEmpty()) {
            riddleTask.markAsDeleted(caseExpression);
        }
    }

    @Override
    public void visit(WhenClause whenClause) {
        whenClause.getWhenExpression().accept(this);
        whenClause.getThenExpression().accept(this);

        if (whenClause.getWhenExpression() instanceof BinaryExpression) {
            whenClause.setWhenExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) whenClause.getWhenExpression()));
        } else if (riddleTask.needToDelete(whenClause.getWhenExpression()) || riddleTask.markedAsDeleted(whenClause.getWhenExpression())) {
            riddleTask.markAsDeleted(whenClause.getWhenExpression());
            whenClause.setWhenExpression(null);
        }
        if (whenClause.getThenExpression() instanceof BinaryExpression) {
            whenClause.setThenExpression(checkAndRepairTopLevelBinaryExpression((BinaryExpression) whenClause.getThenExpression()));
        } else if (riddleTask.needToDelete(whenClause.getThenExpression()) || riddleTask.markedAsDeleted(whenClause.getThenExpression())) {
            riddleTask.markAsDeleted(whenClause.getThenExpression());
            whenClause.setThenExpression(null);
        }
        if (whenClause.getThenExpression() == null || whenClause.getWhenExpression() == null) {
            riddleTask.markAsDeleted(whenClause);
        }
    }

    @Override
    public void visit(AllComparisonExpression allComparisonExpression) {
        allComparisonExpression.GetSubSelect().accept((ExpressionVisitor) this);
    }

    @Override
    public void visit(AnyComparisonExpression anyComparisonExpression) {
        anyComparisonExpression.GetSubSelect().accept((ExpressionVisitor) this);
    }

    @Override
    public void visit(Concat concat) {
        visitBinaryExpression(concat);
    }

    @Override
    public void visit(Matches matches) {
        visitBinaryExpression(matches);
    }

    @Override
    public void visit(BitwiseAnd bitwiseAnd) {
        visitBinaryExpression(bitwiseAnd);
    }

    @Override
    public void visit(BitwiseOr bitwiseOr) {
        visitBinaryExpression(bitwiseOr);
    }

    @Override
    public void visit(BitwiseXor bitwiseXor) {
        visitBinaryExpression(bitwiseXor);
    }

    @Override
    public void visit(Connect aConnect) {
        aConnect.getStartWith().accept(this);
        aConnect.getConnectBy().accept(this);

        if (aConnect.getStartWith() instanceof BinaryExpression) {
            aConnect.setStartWith(checkAndRepairTopLevelBinaryExpression((BinaryExpression) aConnect.getStartWith()));
        } else if (riddleTask.needToDelete(aConnect.getStartWith()) || riddleTask.markedAsDeleted(aConnect.getStartWith())) {
            riddleTask.markAsDeleted(aConnect.getStartWith());
            aConnect.setStartWith(null);
        }
        if (aConnect.getConnectBy() instanceof BinaryExpression) {
            aConnect.setConnectBy(checkAndRepairTopLevelBinaryExpression((BinaryExpression) aConnect.getConnectBy()));
        } else if (riddleTask.needToDelete(aConnect.getConnectBy()) || riddleTask.markedAsDeleted(aConnect.getConnectBy())) {
            riddleTask.markAsDeleted(aConnect.getConnectBy());
            aConnect.setConnectBy(null);
        }
        if (aConnect.getConnectBy() == null) {
            riddleTask.markAsDeleted(aConnect);
        }
    }
}


text:
package com.sezgk.tractor.census;

/**
 * Represents the data for a single state in the United States.
 *
 * @author Ennis Golaszewski
 */
public class StateData
{
    private int stateFIPS;
    private int numDistricts;
    private String stateAbbr;
    private String stateName;
    private MapCoordinate seedCoordinate;

    public StateData(int stateFIPS, int numDistricts, String stateAbbr, String stateName, MapCoordinate seedCoordinate)
    {
        this.stateFIPS = stateFIPS;
        this.numDistricts = numDistricts;
        this.stateAbbr = stateAbbr;
        this.stateName = stateName;
        this.seedCoordinate = seedCoordinate;
    }

    public int getStateFIPS()
    {
        return stateFIPS;
    }

    public int getNumDistricts()
    {
        return numDistricts;
    }

    public String getStateAbbr()
    {
        return stateAbbr;
    }

    public String getStateName()
    {
        return stateName;
    }

    public MapCoordinate getSeedCoordinate()
    {
        return seedCoordinate;
    }
}


text:
              <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
                Button dropdown
              </button>

                  {{widget.name}}

            <button ng-repeat="widget in widgetDefs"
                    ng-click="addWidgetInternal($event, widget);" type="button" class="btn btn-primary">
                {{widget.name}}
            </button>

        <button class="btn btn-warning" ng-click="resetWidgetsToDefault()">Default Widgets</button>

        <button ng-if="options.storage && options.explicitSave" ng-click="options.saveDashboard()" class="btn btn-success" ng-disabled="!options.unsavedChangeCount">{{ !options.unsavedChangeCount ? "all saved" : "save changes (" + options.unsavedChangeCount + ")" }}</button>

        <button ng-click="clear();" type="button" class="btn btn-info">Clear</button>

                        {{widget.title}}
                        <form action="" class="widget-title" ng-show="widget.editingTitle" ng-submit="saveTitleEdit(widget, $event)">
                            <input type="text" ng-model="widget.title" ng-blur="titleLostFocus(widget, $event)" class="form-control">
                        </form>
                        {{widget.name}}


text:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenXmlPowerTools
{
    public class TestUtil
    {
        public static DirectoryInfo SourceDir = new DirectoryInfo("../../../TestFiles/");
        private static bool? s_DeleteTempFiles = null;

        public static bool DeleteTempFiles
        {
            get
            {
                if (s_DeleteTempFiles != null)
                    return (bool)s_DeleteTempFiles;
                FileInfo donotdelete = new FileInfo("donotdelete.txt");
                s_DeleteTempFiles = !donotdelete.Exists;
                return (bool)s_DeleteTempFiles;
            }
        }

        private static DirectoryInfo s_TempDir = null;
        public static DirectoryInfo TempDir
        {
            get
            {
                if (s_TempDir != null)
                    return s_TempDir;
                else
                {
                    var now = DateTime.Now;
                    var tempDirName = String.Format("Test-{0:00}-{1:00}-{2:00}-{3:00}{4:00}{5:00}", now.Year - 2000, now.Month, now.Day, now.Hour, now.Minute, now.Second);
                    s_TempDir = new DirectoryInfo(Path.Combine(".", tempDirName));
                    s_TempDir.Create();
                    return s_TempDir;
                }
            }
        }
    }
}


text:
package org.meluskyc.codebriefcase.activity;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.view.View;
import android.widget.TextView;

import org.meluskyc.codebriefcase.BuildConfig;
import org.meluskyc.codebriefcase.R;

public class AboutActivity extends BaseActivity {

    private static final String REPO_URL = "";

    private View.OnClickListener listener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.about_text_source:
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(REPO_URL)));
                    break;
                case R.id.about_text_licenses:
                    startActivity(new Intent(AboutActivity.this, LicensesActivity.class));
                    break;
            }

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_about);

        Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        TextView main = (TextView) findViewById(R.id.about_text_version);
        TextView sourceLink = (TextView) findViewById(R.id.about_text_source);
        TextView licensesLink = (TextView) findViewById(R.id.about_text_licenses);
        main.setText(Html.fromHtml(getString(R.string.code_briefcase, BuildConfig.VERSION_NAME)));
        sourceLink.setOnClickListener(listener);
        licensesLink.setOnClickListener(listener);
    }
}


text:
This page is specific to database reviews. Please refer to our
[code review guide](code_review.md) for broader advice and best
practices for code review in general.

## General process

A database review is required for:

- Changes that touch the database schema or perform data migrations,
  including files in:
  - `db/`
  - `lib/gitlab/background_migration/`
- Changes to the database tooling. For example:
  - migration or ActiveRecord helpers in `lib/gitlab/database/`
  - load balancing
- Changes that produce SQL queries that are beyond the obvious. It is
  generally up to the author of a merge request to decide whether or
  not complex queries are being introduced and if they require a
  database review.
- Changes in usage data metrics that use `count` and `distinct_count`.
  These metrics could have complex queries over large tables.
  See the [Telemetry Guide](telemetry/usage_ping.md#implementing-usage-ping)
  for implementation details.

A database reviewer is expected to look out for obviously complex
queries in the change and review those closer. If the author does not
point out specific queries for review and there are no obviously
complex queries, it is enough to concentrate on reviewing the
migration only.

It is preferable to review queries in SQL form and generally accepted
to ask the author to translate any ActiveRecord queries in SQL form
for review.

### Roles and process

A Merge Request **author**'s role is to:

- Decide whether a database review is needed.
- If database review is needed, add the ~database label.
- [Prepare the merge request for a database review](#how-to-prepare-the-merge-request-for-a-database-review).

A database **reviewer**'s role is to:

- Perform a first-pass review on the MR and suggest improvements to the author.
- Once satisfied, relabel the MR with ~"database::reviewed", approve it, and
  reassign MR to the database **maintainer** suggested by Reviewer
  Roulette.

A database **maintainer**'s role is to:

- Perform the final database review on the MR.
- Discuss further improvements or other relevant changes with the
  database reviewer and the MR author.
- Finally approve the MR and relabel the MR with ~"database::approved"
- Merge the MR if no other approvals are pending or pass it on to
  other maintainers as required (frontend, backend, docs).

### Distributing review workload

Review workload is distributed using [reviewer roulette](code_review.md#reviewer-roulette)
([example](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25181#note_147551725)).
The MR author should then co-assign the suggested database
**reviewer**. When they give their sign-off, they will hand over to
the suggested database **maintainer**.

If reviewer roulette didn't suggest a database reviewer & maintainer,
make sure you have applied the ~database label and rerun the
`danger-review` CI job, or pick someone from the
[`@gl-database` team](https://gitlab.com/groups/gl-database/-/group_members).

### How to prepare the merge request for a database review

In order to make reviewing easier and therefore faster, please take
the following preparations into account.

#### Preparation when adding migrations

- Ensure `db/structure.sql` is updated as [documented](migration_style_guide.md#schema-changes), and additionally ensure that the relevant version files under
`db/schema_migrations` were added or removed.
- Make migrations reversible by using the `change` method or include a `down` method when using `up`.
  - Include either a rollback procedure or describe how to rollback changes.
- Add the output of both migrating and rolling back for all migrations into the MR description.
  - Ensure the down method reverts the changes in `db/structure.sql`.
  - Update the migration output whenever you modify the migrations during the review process.
- Add tests for the migration in `spec/migrations` if necessary. See [Testing Rails migrations at GitLab](testing_guide/testing_migrations_guide.md) for more details.
- When [high-traffic](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3) tables are involved in the migration, use the [`with_lock_retries`](migration_style_guide.md#retry-mechanism-when-acquiring-database-locks) helper method. Review the relevant [examples in our documentation](migration_style_guide.md#examples) for use cases and solutions.
- Ensure RuboCop checks are not disabled unless there's a valid reason to.
- When adding an index to a [large table](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L3),
test its execution using `CREATE INDEX CONCURRENTLY` in the `#database-lab` Slack channel and add the execution time to the MR description:
  - Execution time largely varies between `#database-lab` and GitLab.com, but an elevated execution time from `#database-lab`
    can give a hint that the execution on GitLab.com will also be considerably high.
  - If the execution from `#database-lab` is longer than `1h`, the index should be moved to a [post-migration](post_deployment_migrations.md).
    Keep in mind that in this case you may need to split the migration and the application changes in separate releases to ensure the index
    will be in place when the code that needs it will be deployed.

#### Preparation when adding or modifying queries

- Write the raw SQL in the MR description. Preferably formatted
  nicely with [pgFormatter](https://sqlformat.darold.net) or
  [paste.depesz.com](https://paste.depesz.com).
- Include the output of `EXPLAIN (ANALYZE, BUFFERS)` of the relevant
  queries in the description. If the output is too long, wrap it in
  `<details>` blocks, paste it in a GitLab Snippet, or provide the
  link to the plan at: [explain.depesz.com](https://explain.depesz.com).
- When providing query plans, make sure it hits enough data:
  - You can use a GitLab production replica to test your queries on a large scale,
  through the `#database-lab` Slack channel or through [chatops](understanding_explain_plans.md#chatops).
  - Usually, the `gitlab-org` namespace (`namespace_id = 9970`) and the
  `gitlab-org/gitlab-foss` (`project_id = 13083`) or the `gitlab-org/gitlab` (`project_id = 278964`)
   projects provide enough data to serve as a good example.
- For query changes, it is best to provide the SQL query along with a
  plan _before_ and _after_ the change. This helps to spot differences
  quickly.
- Include data that shows the performance improvement, preferably in
  the form of a benchmark.

#### Preparation when adding foreign keys to existing tables

- Include a migration to remove orphaned rows in the source table **before** adding the foreign key.
- Remove any instances of `dependent: ...` that may no longer be necessary.

#### Preparation when adding tables

- Order columns based on the [Ordering Table Columns](ordering_table_columns.md) guidelines.
- Add foreign keys to any columns pointing to data in other tables, including [an index](migration_style_guide.md#adding-foreign-key-constraints).
- Add indexes for fields that are used in statements such as `WHERE`, `ORDER BY`, `GROUP BY`, and `JOIN`s.

#### Preparation when removing columns, tables, indexes, or other structures

- Follow the [guidelines on dropping columns](what_requires_downtime.md#dropping-columns).
- Generally it's best practice (but not a hard rule) to remove indexes and foreign keys in a post-deployment migration.
  - Exceptions include removing indexes and foreign keys for small tables.
- If you're adding a composite index, another index might become redundant, so remove that in the same migration.
  For example adding `index(column_A, column_B, column_C)` makes the indexes `index(column_A, column_B)` and `index(column_A)` redundant.

### How to review for database

- Check migrations
  - Review relational modeling and design choices
  - Review migrations follow [database migration style guide](migration_style_guide.md),
    for example
    - [Check ordering of columns](ordering_table_columns.md)
    - [Check indexes are present for foreign keys](migration_style_guide.md#adding-foreign-key-constraints)
  - Ensure that migrations execute in a transaction or only contain
    concurrent index/foreign key helpers (with transactions disabled)
  - If an index to a large table is added and its execution time was elevated (more than 1h) on `#database-lab`:
    - Ensure it was added in a post-migration.
    - Maintainer: After the merge request is merged, notify Release Managers about it on `#f_upcoming_release` Slack channel.
  - Check consistency with `db/structure.sql` and that migrations are [reversible](migration_style_guide.md#reversibility)
  - Check that the relevant version files under `db/schema_migrations` were added or removed.
  - Check queries timing (If any): Queries executed in a migration
    need to fit comfortably within `15s` - preferably much less than that - on GitLab.com.
  - For column removals, make sure the column has been [ignored in a previous release](what_requires_downtime.md#dropping-columns)
- Check [background migrations](background_migrations.md):
  - Establish a time estimate for execution on GitLab.com. For historical purposes,
    it's highly recommended to include this estimation on the merge request description.
  - If a single `update` is below than `1s` the query can be placed
      directly in a regular migration (inside `db/migrate`).
  - Background migrations are normally used, but not limited to:
    - Migrating data in larger tables.
    - Making numerous SQL queries per record in a dataset.
  - Review queries (for example, make sure batch sizes are fine)
  - Because execution time can be longer than for a regular migration,
    it's suggested to treat background migrations as post migrations:
    place them in `db/post_migrate` instead of `db/migrate`. Keep in mind
    that post migrations are executed post-deployment in production.
- Check [timing guidelines for migrations](#timing-guidelines-for-migrations)
- Check migrations are reversible and implement a `#down` method
- Check data migrations:
  - Establish a time estimate for execution on GitLab.com.
  - Depending on timing, data migrations can be placed on regular, post-deploy, or background migrations.
  - Data migrations should be reversible too or come with a description of how to reverse, when possible.
    This applies to all types of migrations (regular, post-deploy, background).
- Query performance
  - Check for any obviously complex queries and queries the author specifically
    points out for review (if any)
  - If not present yet, ask the author to provide SQL queries and query plans
    (for example, by using [chatops](understanding_explain_plans.md#chatops) or direct
    database access)
  - For given queries, review parameters regarding data distribution
  - [Check query plans](understanding_explain_plans.md) and suggest improvements
    to queries (changing the query, schema or adding indexes and similar)
  - General guideline is for queries to come in below 100ms execution time
  - If queries rely on prior migrations that are not present yet on production
    (eg indexes, columns), you can use a [one-off instance from the restore
    pipeline](https://ops.gitlab.net/gitlab-com/gl-infra/gitlab-restore/postgres-gprd)
    in order to establish a proper testing environment. If you don't have access to this project, reach out to #database on Slack to get advice on how to proceed.
  - Avoid N+1 problems and minimalize the [query count](merge_request_performance_guidelines.md#query-counts).

### Timing guidelines for migrations

In general, migrations for a single deploy shouldn't take longer than
1 hour for GitLab.com. The following guidelines are not hard rules, they were
estimated to keep migration timing to a minimum.

NOTE: **Note:**
Keep in mind that all runtimes should be measured against GitLab.com.

| Migration Type | Execution Time Recommended | Notes |
|----|----|---|
| Regular migrations on `db/migrate` | `3 minutes` | A valid exception are index creation as this can take a long time. |
| Post migrations on `db/post_migrate` | `10 minutes` | |
| Background migrations | --- | Since these are suitable for larger tables, it's not possible to set a precise timing guideline, however, any single query must stay below `1 second` execution time with cold caches. |