//go:build !trial
// +build !trial

package rule

import (
	"github.com/actiontech/sqle/sqle/driver/mysql/plocale"
	driverV2 "github.com/actiontech/sqle/sqle/driver/v2"
	"github.com/actiontech/sqle/sqle/pkg/params"
	"github.com/pingcap/parser/ast"
)

var sourceRuleHandlers = []*SourceHandler{
	{
		Rule: SourceRule{
			Name:         DMLNotAllowInsertAutoincrement,
			Desc:         plocale.DMLNotAllowInsertAutoincrementDesc,
			Annotation:   plocale.DMLNotAllowInsertAutoincrementAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
		},
		Message: plocale.DMLNotAllowInsertAutoincrementMessage,
		Func:    notAllowInsertAutoincrement,
	},
	{
		Rule: SourceRule{
			Name:       ConfigDDLOSCMinSize,
			Desc:       plocale.ConfigDDLOSCMinSizeDesc,
			Annotation: plocale.ConfigDDLOSCMinSizeAnnotation,
			//Value:    "16",
			Level:    driverV2.RuleLevelNormal,
			Category: plocale.RuleTypeGlobalConfig,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.ConfigDDLOSCMinSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Func: nil,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckTableSize,
			Desc:       plocale.DDLCheckTableSizeDesc,
			Annotation: plocale.DDLCheckTableSizeAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.DDLCheckTableSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:                 plocale.DDLCheckTableSizeMessage,
		OnlyAuditNotExecutedSQL: true,
		Func:                    checkDDLTableSize,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexTooMany,
			Desc:       plocale.DDLCheckIndexTooManyDesc,
			Annotation: plocale.DDLCheckIndexTooManyAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeIndexingConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "2",
					Desc:  plocale.DDLCheckIndexTooManyParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:                         plocale.DDLCheckIndexTooManyMessage,
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            checkIndex,
	},
	{
		Rule: SourceRule{
			Name:       ConfigDMLExplainPreCheckEnable,
			Desc:       plocale.ConfigDMLExplainPreCheckEnableDesc,
			Annotation: plocale.ConfigDMLExplainPreCheckEnableAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeGlobalConfig,
		},
		Func: nil,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckRedundantIndex,
			Desc:         plocale.DDLCheckRedundantIndexDesc,
			Annotation:   plocale.DDLCheckRedundantIndexAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexOptimization,
			AllowOffline: true,
		},
		Message:                         plocale.DDLCheckRedundantIndexMessage,
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            checkIndex,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckTableSize,
			Desc:       plocale.DMLCheckTableSizeDesc,
			Annotation: plocale.DMLCheckTableSizeAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.DMLCheckTableSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckTableSizeMessage,
		Func:    checkDMLTableSize,
	},
	{
		Rule: SourceRule{
			Name:       ConfigOptimizeIndexEnabled,
			Desc:       plocale.ConfigOptimizeIndexEnabledDesc,
			Annotation: plocale.ConfigOptimizeIndexEnabledAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeIndexOptimization,
			Params: []*SourceParam{
				{
					Key:   DefaultMultiParamsFirstKeyName,
					Value: "2.00",
					Desc:  plocale.ConfigOptimizeIndexEnabledParams1,
					Type:  params.ParamTypeFloat64,
				},
				{
					Key:   DefaultMultiParamsSecondKeyName,
					Value: "3",
					Desc:  plocale.ConfigOptimizeIndexEnabledParams2,
					Type:  params.ParamTypeInt,
				},
			},
		},
	},

	{
		Rule: SourceRule{
			Name:       ConfigSQLIsExecuted,
			Desc:       plocale.ConfigSQLIsExecutedDesc,
			Annotation: plocale.ConfigSQLIsExecutedAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeGlobalConfig,
		},
	},

	{
		Rule: SourceRule{
			Name:       ConfigDDLGhostMinSize,
			Desc:       plocale.ConfigDDLGhostMinSizeDesc,
			Annotation: plocale.ConfigDDLGhostMinSizeAnnotation,
			//Value:    "16",
			Level:    driverV2.RuleLevelNormal,
			Category: plocale.RuleTypeGlobalConfig,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.ConfigDDLGhostMinSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Func: nil,
	},

	// rule
	{
		Rule: SourceRule{
			Name:         DDLCheckPKWithoutIfNotExists,
			Desc:         plocale.DDLCheckPKWithoutIfNotExistsDesc,
			Annotation:   plocale.DDLCheckPKWithoutIfNotExistsAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckPKWithoutIfNotExistsMessage,
		Func:    checkIfNotExist,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckObjectNameLength,
			Desc:         plocale.DDLCheckObjectNameLengthDesc,
			Annotation:   plocale.DDLCheckObjectNameLengthAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeNamingConvention,
			AllowOffline: true,
			//Value:    "64",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "64",
					Desc:  plocale.DDLCheckObjectNameLengthParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckObjectNameLengthMessage,
		Func:    checkNewObjectName,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckObjectNameIsUpperAndLowerLetterMixed,
			Desc:         plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedDesc,
			Annotation:   plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedAnnotation,
			Category:     plocale.RuleTypeNamingConvention,
			Level:        driverV2.RuleLevelNotice,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedMessage,
		Func:    checkIsObjectNameUpperAndLowerLetterMixed,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckPKNotExist,
			Desc:         plocale.DDLCheckPKNotExistDesc,
			Annotation:   plocale.DDLCheckPKNotExistAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
		},
		Message:                         plocale.DDLCheckPKNotExistMessage,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                            checkPrimaryKey,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckPKWithoutAutoIncrement,
			Desc:         plocale.DDLCheckPKWithoutAutoIncrementDesc,
			Annotation:   plocale.DDLCheckPKWithoutAutoIncrementAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
		},
		Message:                         plocale.DDLCheckPKWithoutAutoIncrementMessage,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                            checkPrimaryKey,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckPKWithoutBigintUnsigned,
			Desc:         plocale.DDLCheckPKWithoutBigintUnsignedDesc,
			Annotation:   plocale.DDLCheckPKWithoutBigintUnsignedAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
		},
		Message:                         plocale.DDLCheckPKWithoutBigintUnsignedMessage,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                            checkPrimaryKey,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckJoinFieldType,
			Desc:       plocale.DMLCheckJoinFieldTypeDesc,
			Annotation: plocale.DMLCheckJoinFieldTypeAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckJoinFieldTypeMessage,
		Func:    checkJoinFieldType,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckHasJoinCondition,
			Desc:         plocale.DMLCheckHasJoinConditionDesc,
			Annotation:   plocale.DMLCheckHasJoinConditionAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckHasJoinConditionMessage,
		Func:    checkHasJoinCondition,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnCharLength,
			Desc:         plocale.DDLCheckColumnCharLengthDesc,
			Annotation:   plocale.DDLCheckColumnCharLengthAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnCharLengthMessage,
		Func:    checkStringType,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckFieldNotNUllMustContainDefaultValue,
			Desc:         plocale.DDLCheckFieldNotNUllMustContainDefaultValueDesc,
			Annotation:   plocale.DDLCheckFieldNotNUllMustContainDefaultValueAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckFieldNotNUllMustContainDefaultValueMessage,
		Func:    checkFieldNotNUllMustContainDefaultValue,
	},
	{
		Rule: SourceRule{
			Name:         DDLDisableFK,
			Desc:         plocale.DDLDisableFKDesc,
			Annotation:   plocale.DDLDisableFKAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLDisableFKMessage,
		Func:    checkForeignKey,
	},
	{
		Rule: SourceRule{
			Name:         DDLDisableAlterFieldUseFirstAndAfter,
			Desc:         plocale.DDLDisableAlterFieldUseFirstAndAfterDesc,
			Annotation:   plocale.DDLDisableAlterFieldUseFirstAndAfterAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLDisableAlterFieldUseFirstAndAfterMessage,
		Func:    disableAlterUseFirstAndAfter,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckCreateTimeColumn,
			Desc:         plocale.DDLCheckCreateTimeColumnDesc,
			Annotation:   plocale.DDLCheckCreateTimeColumnAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "CREATE_TIME",
					Desc:  plocale.DDLCheckCreateTimeColumnParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckCreateTimeColumnMessage,
		Func:    checkFieldCreateTime,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexCount,
			Desc:       plocale.DDLCheckIndexCountDesc,
			Annotation: plocale.DDLCheckIndexCountAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "5",
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "5",
					Desc:  plocale.DDLCheckIndexCountParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:                         plocale.DDLCheckIndexCountMessage,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            checkIndex,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckUpdateTimeColumn,
			Desc:         plocale.DDLCheckUpdateTimeColumnDesc,
			Annotation:   plocale.DDLCheckUpdateTimeColumnAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "UPDATE_TIME",
					Desc:  plocale.DDLCheckUpdateTimeColumnParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckUpdateTimeColumnMessage,
		Func:    checkFieldUpdateTime,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCompositeIndexMax,
			Desc:       plocale.DDLCheckCompositeIndexMaxDesc,
			Annotation: plocale.DDLCheckCompositeIndexMaxAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "3",
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "3",
					Desc:  plocale.DDLCheckCompositeIndexMaxParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:                         plocale.DDLCheckCompositeIndexMaxMessage,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            checkIndex,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckIndexNotNullConstraint,
			Desc:         plocale.DDLCheckIndexNotNullConstraintDesc,
			Annotation:   plocale.DDLCheckIndexNotNullConstraintAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
		},
		Message:              plocale.DDLCheckIndexNotNullConstraintMessage,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                 checkIndexNotNullConstraint,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckObjectNameUsingKeyword,
			Desc:         plocale.DDLCheckObjectNameUsingKeywordDesc,
			Annotation:   plocale.DDLCheckObjectNameUsingKeywordAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeNamingConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckObjectNameUsingKeywordMessage,
		Func:    checkNewObjectName,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckObjectNameUseCN,
			Desc:         plocale.DDLCheckObjectNameUseCNDesc,
			Annotation:   plocale.DDLCheckObjectNameUseCNAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeNamingConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckObjectNameUseCNMessage,
		Func:    checkNewObjectName,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckTableDBEngine,
			Desc:         plocale.DDLCheckTableDBEngineDesc,
			Annotation:   plocale.DDLCheckTableDBEngineAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: false,
			//Value:    "Innodb",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "Innodb",
					Desc:  plocale.DDLCheckTableDBEngineParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckTableDBEngineMessage,
		Func:    checkEngine,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckTableCharacterSet,
			Desc:         plocale.DDLCheckTableCharacterSetDesc,
			Annotation:   plocale.DDLCheckTableCharacterSetAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: false,
			//Value:    "utf8mb4",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "utf8mb4",
					Desc:  plocale.DDLCheckTableCharacterSetParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckTableCharacterSetMessage,
		Func:    checkCharacterSet,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckIndexedColumnWithBlob,
			Desc:         plocale.DDLCheckIndexedColumnWithBlobDesc,
			Annotation:   plocale.DDLCheckIndexedColumnWithBlobAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
		},
		Message:                         plocale.DDLCheckIndexedColumnWithBlobMessage,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            disableAddIndexForColumnsTypeBlob,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckWhereIsInvalid,
			Desc:         plocale.DMLCheckWhereIsInvalidDesc,
			Annotation:   plocale.DMLCheckWhereIsInvalidAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckWhereIsInvalidMessage,
		Func:    checkSelectWhere,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckAlterTableNeedMerge,
			Desc:         plocale.DDLCheckAlterTableNeedMergeDesc,
			Annotation:   plocale.DDLCheckAlterTableNeedMergeAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: false,
		},
		Message:                 plocale.DDLCheckAlterTableNeedMergeMessage,
		OnlyAuditNotExecutedSQL: true,
		Func:                    checkMergeAlterTable,
	},
	{
		Rule: SourceRule{
			Name:         DMLDisableSelectAllColumn,
			Desc:         plocale.DMLDisableSelectAllColumnDesc,
			Annotation:   plocale.DMLDisableSelectAllColumnAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLDisableSelectAllColumnMessage,
		Func:    checkSelectAll,
	},
	{
		Rule: SourceRule{
			Name:         DDLDisableDropStatement,
			Desc:         plocale.DDLDisableDropStatementDesc,
			Annotation:   plocale.DDLDisableDropStatementAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLDisableDropStatementMessage,
		Func:    disableDropStmt,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckTableWithoutComment,
			Desc:         plocale.DDLCheckTableWithoutCommentDesc,
			Annotation:   plocale.DDLCheckTableWithoutCommentAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckTableWithoutCommentMessage,
		Func:    checkTableWithoutComment,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnWithoutComment,
			Desc:         plocale.DDLCheckColumnWithoutCommentDesc,
			Annotation:   plocale.DDLCheckColumnWithoutCommentAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnWithoutCommentMessage,
		Func:    checkColumnWithoutComment,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckIndexPrefix,
			Desc:         plocale.DDLCheckIndexPrefixDesc,
			Annotation:   plocale.DDLCheckIndexPrefixAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeNamingConvention,
			AllowOffline: true,
			//Value:    "idx_",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "idx_",
					Desc:  plocale.DDLCheckIndexPrefixParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckIndexPrefixMessage,
		Func:    checkIndexPrefix,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckUniqueIndexPrefix,
			Desc:         plocale.DDLCheckUniqueIndexPrefixDesc,
			Annotation:   plocale.DDLCheckUniqueIndexPrefixAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeNamingConvention,
			AllowOffline: true,
			//Value:    "uniq_",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "uniq_",
					Desc:  plocale.DDLCheckUniqueIndexPrefixParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckUniqueIndexPrefixMessage,
		Func:    checkUniqIndexPrefix,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckUniqueIndex,
			Desc:         plocale.DDLCheckUniqueIndexDesc,
			Annotation:   plocale.DDLCheckUniqueIndexAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeNamingConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckUniqueIndexMessage,
		Func:    checkUniqIndex,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnWithoutDefault,
			Desc:         plocale.DDLCheckColumnWithoutDefaultDesc,
			Annotation:   plocale.DDLCheckColumnWithoutDefaultAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnWithoutDefaultMessage,
		Func:    checkColumnWithoutDefault,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnTimestampWithoutDefault,
			Desc:         plocale.DDLCheckColumnTimestampWithoutDefaultDesc,
			Annotation:   plocale.DDLCheckColumnTimestampWithoutDefaultAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnTimestampWithoutDefaultMessage,
		Func:    checkColumnTimestampWithoutDefault,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnBlobWithNotNull,
			Desc:         plocale.DDLCheckColumnBlobWithNotNullDesc,
			Annotation:   plocale.DDLCheckColumnBlobWithNotNullAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnBlobWithNotNullMessage,
		Func:    checkColumnBlobNotNull,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnBlobDefaultIsNotNull,
			Desc:         plocale.DDLCheckColumnBlobDefaultIsNotNullDesc,
			Annotation:   plocale.DDLCheckColumnBlobDefaultIsNotNullAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnBlobDefaultIsNotNullMessage,
		Func:    checkColumnBlobDefaultNull,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckAutoIncrementFieldNum,
			Desc:         plocale.DDLCheckAutoIncrementFieldNumDesc,
			Annotation:   plocale.DDLCheckAutoIncrementFieldNumAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckAutoIncrementFieldNumMessage,
		Func:    checkAutoIncrementFieldNum,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckAllIndexNotNullConstraint,
			Desc:         plocale.DDLCheckAllIndexNotNullConstraintDesc,
			Annotation:   plocale.DDLCheckAllIndexNotNullConstraintAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckAllIndexNotNullConstraintMessage,
		Func:    checkAllIndexNotNullConstraint,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckWithLimit,
			Desc:         plocale.DMLCheckWithLimitDesc,
			Annotation:   plocale.DMLCheckWithLimitAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckWithLimitMessage,
		Func:    checkDMLWithLimit,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckSelectLimit,
			Desc:         plocale.DMLCheckSelectLimitDesc,
			Annotation:   plocale.DMLCheckSelectLimitAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1000",
					Desc:  plocale.DMLCheckSelectLimitParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckSelectLimitMessage,
		Func:    checkSelectLimit,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckWithOrderBy,
			Desc:         plocale.DMLCheckWithOrderByDesc,
			Annotation:   plocale.DMLCheckWithOrderByAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckWithOrderByMessage,
		Func:    checkDMLWithOrderBy,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckSelectWithOrderBy,
			Desc:         plocale.DMLCheckSelectWithOrderByDesc,
			Annotation:   plocale.DMLCheckSelectWithOrderByAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckSelectWithOrderByMessage,
		Func:    checkSelectWithOrderBy,
	},
	{
		// TODO: 修改level以适配默认模板
		Rule: SourceRule{
			Name:         DMLCheckInsertColumnsExist,
			Desc:         plocale.DMLCheckInsertColumnsExistDesc,
			Annotation:   plocale.DMLCheckInsertColumnsExistAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckInsertColumnsExistMessage,
		Func:    checkDMLWithInsertColumnExist,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckBatchInsertListsMax,
			Desc:       plocale.DMLCheckBatchInsertListsMaxDesc,
			Annotation: plocale.DMLCheckBatchInsertListsMaxAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "5000",
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "100",
					Desc:  plocale.DMLCheckBatchInsertListsMaxParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckBatchInsertListsMaxMessage,
		Func:    checkDMLWithBatchInsertMaxLimits,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckInQueryNumber,
			Desc:         plocale.DMLCheckInQueryNumberDesc,
			Annotation:   plocale.DMLCheckInQueryNumberAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "50",
					Desc:  plocale.DMLCheckInQueryNumberParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckInQueryNumberMessage,
		Func:    checkInQueryLimit,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckPKProhibitAutoIncrement,
			Desc:         plocale.DDLCheckPKProhibitAutoIncrementDesc,
			Annotation:   plocale.DDLCheckPKProhibitAutoIncrementAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeIndexingConvention,
			AllowOffline: true,
		},
		Message:                         plocale.DDLCheckPKProhibitAutoIncrementMessage,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                            checkPrimaryKey,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckWhereExistFunc,
			Desc:         plocale.DMLCheckWhereExistFuncDesc,
			Annotation:   plocale.DMLCheckWhereExistFuncAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckWhereExistFuncMessage,
		Func:    checkWhereExistFunc,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckWhereExistNot,
			Desc:         plocale.DMLCheckWhereExistNotDesc,
			Annotation:   plocale.DMLCheckWhereExistNotAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckWhereExistNotMessage,
		Func:    checkSelectWhere,
	},
	{
		Rule: SourceRule{
			Name:         DMLWhereExistNull,
			Desc:         plocale.DMLWhereExistNullDesc,
			Annotation:   plocale.DMLWhereExistNullAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLWhereExistNullMessage,
		Func:    checkWhereExistNull,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckWhereExistImplicitConversion,
			Desc:       plocale.DMLCheckWhereExistImplicitConversionDesc,
			Annotation: plocale.DMLCheckWhereExistImplicitConversionAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckWhereExistImplicitConversionMessage,
		Func:    checkWhereColumnImplicitConversion,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckLimitMustExist,
			Desc:         plocale.DMLCheckLimitMustExistDesc,
			Annotation:   plocale.DMLCheckLimitMustExistAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckLimitMustExistMessage,
		Func:    checkDMLLimitExist,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckWhereExistScalarSubquery,
			Desc:         plocale.DMLCheckWhereExistScalarSubqueryDesc,
			Annotation:   plocale.DMLCheckWhereExistScalarSubqueryAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckWhereExistScalarSubqueryMessage,
		Func:    checkSelectWhere,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexesExistBeforeCreateConstraints,
			Desc:       plocale.DDLCheckIndexesExistBeforeCreateConstraintsDesc,
			Annotation: plocale.DDLCheckIndexesExistBeforeCreateConstraintsAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:                 plocale.DDLCheckIndexesExistBeforeCreateConstraintsMessage,
		OnlyAuditNotExecutedSQL: true,
		Func:                    checkIndexesExistBeforeCreatConstraints,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckSelectForUpdate,
			Desc:         plocale.DMLCheckSelectForUpdateDesc,
			Annotation:   plocale.DMLCheckSelectForUpdateAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckSelectForUpdateMessage,
		Func:    checkDMLSelectForUpdate,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckDatabaseCollation,
			Desc:       plocale.DDLCheckDatabaseCollationDesc,
			Annotation: plocale.DDLCheckDatabaseCollationAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "utf8mb4_0900_ai_ci",
			Category: plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "utf8mb4_0900_ai_ci",
					Desc:  plocale.DDLCheckDatabaseCollationParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckDatabaseCollationMessage,
		Func:    checkCollationDatabase,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckDecimalTypeColumn,
			Desc:         plocale.DDLCheckDecimalTypeColumnDesc,
			Annotation:   plocale.DDLCheckDecimalTypeColumnAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckDecimalTypeColumnMessage,
		Func:    checkDecimalTypeColumn,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckBigintInsteadOfDecimal,
			Desc:         plocale.DDLCheckBigintInsteadOfDecimalDesc,
			Annotation:   plocale.DDLCheckBigintInsteadOfDecimalAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckBigintInsteadOfDecimalMessage,
		Func:    checkBigintInsteadOfDecimal,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckSubQueryNestNum,
			Desc:         plocale.DMLCheckSubQueryNestNumDesc,
			Annotation:   plocale.DMLCheckSubQueryNestNumAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "3",
					Desc:  plocale.DMLCheckSubQueryNestNumParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckSubQueryNestNumMessage,
		Func:    checkSubQueryNestNum,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckNeedlessFunc,
			Desc:       plocale.DMLCheckNeedlessFuncDesc,
			Annotation: plocale.DMLCheckNeedlessFuncAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "sha(),sqrt(),md5()",
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "sha(),sqrt(),md5()",
					Desc:  plocale.DMLCheckNeedlessFuncParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DMLCheckNeedlessFuncMessage,
		Func:    checkNeedlessFunc,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckDatabaseSuffix,
			Desc:         plocale.DDLCheckDatabaseSuffixDesc,
			Annotation:   plocale.DDLCheckDatabaseSuffixAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeNamingConvention,
			AllowOffline: true,
			//Value:    "_DB",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "_DB",
					Desc:  plocale.DDLCheckDatabaseSuffixParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckDatabaseSuffixMessage,
		Func:    checkDatabaseSuffix,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckPKName,
			Desc:         plocale.DDLCheckPKNameDesc,
			Annotation:   plocale.DDLCheckPKNameAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeNamingConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckPKNameMessage,
		Func:    checkPKIndexName,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckTransactionIsolationLevel,
			Desc:         plocale.DDLCheckTransactionIsolationLevelDesc,
			Annotation:   plocale.DDLCheckTransactionIsolationLevelAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckTransactionIsolationLevelMessage,
		Func:    checkTransactionIsolationLevel,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckFuzzySearch,
			Desc:         plocale.DMLCheckFuzzySearchDesc,
			Annotation:   plocale.DMLCheckFuzzySearchAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckFuzzySearchMessage,
		Func:    checkSelectWhere,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckTablePartition,
			Desc:         plocale.DDLCheckTablePartitionDesc,
			Annotation:   plocale.DDLCheckTablePartitionAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckTablePartitionMessage,
		Func:    checkTablePartition,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckNumberOfJoinTables,
			Desc:       plocale.DMLCheckNumberOfJoinTablesDesc,
			Annotation: plocale.DMLCheckNumberOfJoinTablesAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "3",
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "3",
					Desc:  plocale.DMLCheckNumberOfJoinTablesParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckNumberOfJoinTablesMessage,
		Func:    checkNumberOfJoinTables,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckIfAfterUnionDistinct,
			Desc:         plocale.DMLCheckIfAfterUnionDistinctDesc,
			Annotation:   plocale.DMLCheckIfAfterUnionDistinctAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckIfAfterUnionDistinctMessage,
		Func:    checkIsAfterUnionDistinct,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckIsExistLimitOffset,
			Desc:         plocale.DDLCheckIsExistLimitOffsetDesc,
			Annotation:   plocale.DDLCheckIsExistLimitOffsetAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckIsExistLimitOffsetMessage,
		Func:    checkIsExistLimitOffset,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexOption,
			Desc:       plocale.DDLCheckIndexOptionDesc,
			Annotation: plocale.DDLCheckIndexOptionAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "0.7",
			Category:     plocale.RuleTypeIndexOptimization,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "70",
					Desc:  plocale.DDLCheckIndexOptionParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckIndexOptionMessage,
		Func:    checkIndexOption,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnEnumNotice,
			Desc:         plocale.DDLCheckColumnEnumNoticeDesc,
			Annotation:   plocale.DDLCheckColumnEnumNoticeAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnEnumNoticeMessage,
		Func:    checkColumnEnumNotice,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnSetNotice,
			Desc:         plocale.DDLCheckColumnSetNoticeDesc,
			Annotation:   plocale.DDLCheckColumnSetNoticeAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnSetNoticeMessage,
		Func:    checkColumnSetNotice,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnBlobNotice,
			Desc:         plocale.DDLCheckColumnBlobNoticeDesc,
			Annotation:   plocale.DDLCheckColumnBlobNoticeAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckColumnBlobNoticeMessage,
		Func:    checkColumnBlobNotice,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckExplainAccessTypeAll,
			Desc:         plocale.DMLCheckExplainAccessTypeAllDesc,
			Annotation:   plocale.DMLCheckExplainAccessTypeAllAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "10000",
					Desc:  plocale.DMLCheckExplainAccessTypeAllParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckExplainAccessTypeAllMessage,
		Func:    checkExplain,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckExplainExtraUsingFilesort,
			Desc:         plocale.DMLCheckExplainExtraUsingFilesortDesc,
			Annotation:   plocale.DMLCheckExplainExtraUsingFilesortAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckExplainExtraUsingFilesortMessage,
		Func:    checkExplain,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckExplainExtraUsingTemporary,
			Desc:         plocale.DMLCheckExplainExtraUsingTemporaryDesc,
			Annotation:   plocale.DMLCheckExplainExtraUsingTemporaryAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckExplainExtraUsingTemporaryMessage,
		Func:    checkExplain,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckCreateView,
			Desc:         plocale.DDLCheckCreateViewDesc,
			Annotation:   plocale.DDLCheckCreateViewAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckCreateViewMessage,
		Func:    checkCreateView,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckCreateTrigger,
			Desc:         plocale.DDLCheckCreateTriggerDesc,
			Annotation:   plocale.DDLCheckCreateTriggerAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckCreateTriggerMessage,
		Func:    checkCreateTrigger,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckCreateFunction,
			Desc:         plocale.DDLCheckCreateFunctionDesc,
			Annotation:   plocale.DDLCheckCreateFunctionAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckCreateFunctionMessage,
		Func:    checkCreateFunction,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckCreateProcedure,
			Desc:         plocale.DDLCheckCreateProcedureDesc,
			Annotation:   plocale.DDLCheckCreateProcedureAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLCheckCreateProcedureMessage,
		Func:    checkCreateProcedure,
	},
	{
		Rule: SourceRule{
			Name:         DDLDisableTypeTimestamp,
			Desc:         plocale.DDLDisableTypeTimestampDesc,
			Annotation:   plocale.DDLDisableTypeTimestampAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLDisableTypeTimestampMessage,
		Func:    disableUseTypeTimestampField,
	},
	{
		Rule: SourceRule{ //select a as id, id , b as user  from mysql.user;
			Name:       DMLCheckAlias,
			Desc:       plocale.DMLCheckAliasDesc,
			Annotation: plocale.DMLCheckAliasAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckAliasMessage,
		Func:    checkAlias,
	},
	{
		Rule: SourceRule{ //ALTER TABLE test CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
			Name:       DDLHintUpdateTableCharsetWillNotUpdateFieldCharset,
			Desc:       plocale.DDLHintUpdateTableCharsetWillNotUpdateFieldCharsetDesc,
			Annotation: plocale.DDLHintUpdateTableCharsetWillNotUpdateFieldCharsetAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLHintUpdateTableCharsetWillNotUpdateFieldCharsetMessage,
		Func:    hintUpdateTableCharsetWillNotUpdateFieldCharset,
	},
	{
		Rule: SourceRule{ //ALTER TABLE tbl DROP COLUMN col;
			Name:       DDLHintDropColumn,
			Desc:       plocale.DDLHintDropColumnDesc,
			Annotation: plocale.DDLHintDropColumnAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLHintDropColumnMessage,
		Func:    hintDropColumn,
	},
	{
		Rule: SourceRule{ //ALTER TABLE tbl DROP PRIMARY KEY;
			Name:       DDLHintDropPrimaryKey,
			Desc:       plocale.DDLHintDropPrimaryKeyDesc,
			Annotation: plocale.DDLHintDropPrimaryKeyAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLHintDropPrimaryKeyMessage,
		Func:    hintDropPrimaryKey,
	},
	{
		Rule: SourceRule{ //ALTER TABLE tbl DROP FOREIGN KEY a;
			Name:       DDLHintDropForeignKey,
			Desc:       plocale.DDLHintDropForeignKeyDesc,
			Annotation: plocale.DDLHintDropForeignKeyAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLHintDropForeignKeyMessage,
		Func:    hintDropForeignKey,
	},
	{
		Rule: SourceRule{ //select * from user where id like "a";
			Name:       DMLNotRecommendNotWildcardLike,
			Desc:       plocale.DMLNotRecommendNotWildcardLikeDesc,
			Annotation: plocale.DMLNotRecommendNotWildcardLikeAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendNotWildcardLikeMessage,
		Func:    notRecommendNotWildcardLike,
	},
	{
		Rule: SourceRule{ //SELECT * FROM tb WHERE col IN (NULL);
			Name:       DMLHintInNullOnlyFalse,
			Desc:       plocale.DMLHintInNullOnlyFalseDesc,
			Annotation: plocale.DMLHintInNullOnlyFalseAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintInNullOnlyFalseMessage,
		Func:    hintInNullOnlyFalse,
	},
	{
		Rule: SourceRule{ //select * from user where id in (a);
			Name:       DMLNotRecommendIn,
			Desc:       plocale.DMLNotRecommendInDesc,
			Annotation: plocale.DMLNotRecommendInAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendInMessage,
		Func:    notRecommendIn,
	},
	{
		Rule: SourceRule{ //select * from user where id = ' 1';
			Name:       DMLCheckSpacesAroundTheString,
			Desc:       plocale.DMLCheckSpacesAroundTheStringDesc,
			Annotation: plocale.DMLCheckSpacesAroundTheStringAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckSpacesAroundTheStringMessage,
		Func:    checkSpacesAroundTheString,
	},
	{
		Rule: SourceRule{ //CREATE TABLE tb (a varchar(10) default '“');
			Name:       DDLCheckFullWidthQuotationMarks,
			Desc:       plocale.DDLCheckFullWidthQuotationMarksDesc,
			Annotation: plocale.DDLCheckFullWidthQuotationMarksAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLCheckFullWidthQuotationMarksMessage,
		Func:    checkFullWidthQuotationMarks,
	},
	{
		Rule: SourceRule{ //select name from tbl where id < 1000 order by rand(1)
			Name:       DMLNotRecommendOrderByRand,
			Desc:       plocale.DMLNotRecommendOrderByRandDesc,
			Annotation: plocale.DMLNotRecommendOrderByRandAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendOrderByRandMessage,
		Func:    notRecommendOrderByRand,
	},
	{
		Rule: SourceRule{ //select col1,col2 from tbl group by 1
			Name:       DMLNotRecommendGroupByConstant,
			Desc:       plocale.DMLNotRecommendGroupByConstantDesc,
			Annotation: plocale.DMLNotRecommendGroupByConstantAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendGroupByConstantMessage,
		Func:    notRecommendGroupByConstant,
	},
	{
		Rule: SourceRule{ //select c1,c2,c3 from t1 where c1='foo' order by c2 desc, c3 asc
			Name:       DMLCheckSortDirection,
			Desc:       plocale.DMLCheckSortDirectionDesc,
			Annotation: plocale.DMLCheckSortDirectionAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckSortDirectionMessage,
		Func:    checkSortDirection,
	},
	{
		Rule: SourceRule{ //select col1,col2 from tbl group by 1
			Name:       DMLHintGroupByRequiresConditions,
			Desc:       plocale.DMLHintGroupByRequiresConditionsDesc,
			Annotation: plocale.DMLHintGroupByRequiresConditionsAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintGroupByRequiresConditionsMessage,
		Func:    hintGroupByRequiresConditions,
	},
	{
		Rule: SourceRule{ //select description from film where title ='ACADEMY DINOSAUR' order by length-language_id;
			Name:       DMLNotRecommendGroupByExpression,
			Desc:       plocale.DMLNotRecommendGroupByExpressionDesc,
			Annotation: plocale.DMLNotRecommendGroupByExpressionAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendGroupByExpressionMessage,
		Func:    notRecommendGroupByExpression,
	},
	{
		Rule: SourceRule{ //select description from film where title ='ACADEMY DINOSAUR' order by length-language_id;
			Name:       DMLCheckSQLLength,
			Desc:       plocale.DMLCheckSQLLengthDesc,
			Annotation: plocale.DMLCheckSQLLengthAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.DMLCheckSQLLengthParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckSQLLengthMessage,
		Func:    checkSQLLength,
	},
	{
		Rule: SourceRule{ //SELECT s.c_id,count(s.c_id) FROM s where c = test GROUP BY s.c_id HAVING s.c_id <> '1660' AND s.c_id <> '2' order by s.c_id
			Name:       DMLNotRecommendHaving,
			Desc:       plocale.DMLNotRecommendHavingDesc,
			Annotation: plocale.DMLNotRecommendHavingAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendHavingMessage,
		Func:    notRecommendHaving,
	},
	{
		Rule: SourceRule{ //delete from tbl
			Name:       DMLHintUseTruncateInsteadOfDelete,
			Desc:       plocale.DMLHintUseTruncateInsteadOfDeleteDesc,
			Annotation: plocale.DMLHintUseTruncateInsteadOfDeleteAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintUseTruncateInsteadOfDeleteMessage,
		Func:    hintUseTruncateInsteadOfDelete,
	},
	{
		Rule: SourceRule{ //update mysql.func set name ="hello";
			Name:       DMLNotRecommendUpdatePK,
			Desc:       plocale.DMLNotRecommendUpdatePKDesc,
			Annotation: plocale.DMLNotRecommendUpdatePKAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendUpdatePKMessage,
		Func:    notRecommendUpdatePK,
	},
	{
		Rule: SourceRule{ //create table t(c1 int,c2 int,c3 int,c4 int,c5 int,c6 int);
			Name:         DDLCheckColumnQuantity,
			Desc:         plocale.DDLCheckColumnQuantityDesc,
			Annotation:   plocale.DDLCheckColumnQuantityAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "40",
					Desc:  plocale.DDLCheckColumnQuantityParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckColumnQuantityMessage,
		Func:    checkColumnQuantity,
	},
	{
		Rule: SourceRule{ //CREATE TABLE `tb2` ( `id` int(11) DEFAULT NULL, `col` char(10) CHARACTER SET utf8 DEFAULT NULL)
			Name:       DDLRecommendTableColumnCharsetSame,
			Desc:       plocale.DDLRecommendTableColumnCharsetSameDesc,
			Annotation: plocale.DDLRecommendTableColumnCharsetSameAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLRecommendTableColumnCharsetSameMessage,
		Func:    recommendTableColumnCharsetSame,
	},
	{
		Rule: SourceRule{ //CREATE TABLE tab (a INT(1));
			Name:       DDLCheckColumnTypeInteger,
			Desc:       plocale.DDLCheckColumnTypeIntegerDesc,
			Annotation: plocale.DDLCheckColumnTypeIntegerAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLCheckColumnTypeIntegerMessage,
		Func:    checkColumnTypeInteger,
	},
	{
		Rule: SourceRule{ //CREATE TABLE tab (a varchar(3500));
			Name:       DDLCheckVarcharSize,
			Desc:       plocale.DDLCheckVarcharSizeDesc,
			Annotation: plocale.DDLCheckVarcharSizeAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.DDLCheckVarcharSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckVarcharSizeMessage,
		Func:    checkVarcharSize,
	},
	{
		Rule: SourceRule{ //select id from t where substring(name,1,3)='abc'
			Name:       DMLNotRecommendFuncInWhere,
			Desc:       plocale.DMLNotRecommendFuncInWhereDesc,
			Annotation: plocale.DMLNotRecommendFuncInWhereAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendFuncInWhereMessage,
		Func:    notRecommendFuncInWhere,
	},
	{
		Rule: SourceRule{ //SELECT SYSDATE();
			Name:       DMLNotRecommendSysdate,
			Desc:       plocale.DMLNotRecommendSysdateDesc,
			Annotation: plocale.DMLNotRecommendSysdateAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendSysdateMessage,
		Func:    notRecommendSysdate,
	},
	{
		Rule: SourceRule{ //SELECT SUM(COL) FROM tbl;
			Name:       DMLHintSumFuncTips,
			Desc:       plocale.DMLHintSumFuncTipsDesc,
			Annotation: plocale.DMLHintSumFuncTipsAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintSumFuncTipsMessage,
		Func:    hintSumFuncTips,
	},
	{
		Rule: SourceRule{
			Name:         DMLHintCountFuncWithCol,
			Desc:         plocale.DMLHintCountFuncWithColDesc,
			Annotation:   plocale.DMLHintCountFuncWithColAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLHintCountFuncWithColMessage,
		Func:    hintCountFuncWithCol,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnQuantityInPK,
			Desc:       plocale.DDLCheckColumnQuantityInPKDesc,
			Annotation: plocale.DDLCheckColumnQuantityInPKAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "2",
					Desc:  plocale.DDLCheckColumnQuantityInPKParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckColumnQuantityInPKMessage,
		Func:    checkColumnQuantityInPK,
	},
	{
		Rule: SourceRule{ //select col1,col2 from tbl where name=xx limit 10
			Name:       DMLHintLimitMustBeCombinedWithOrderBy,
			Desc:       plocale.DMLHintLimitMustBeCombinedWithOrderByDesc,
			Annotation: plocale.DMLHintLimitMustBeCombinedWithOrderByAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintLimitMustBeCombinedWithOrderByMessage,
		Func:    hintLimitMustBeCombinedWithOrderBy,
	},
	{
		Rule: SourceRule{ //TRUNCATE TABLE tbl_name
			Name:       DMLHintTruncateTips,
			Desc:       plocale.DMLHintTruncateTipsDesc,
			Annotation: plocale.DMLHintTruncateTipsAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintTruncateTipsMessage,
		Func:    hintTruncateTips,
	},
	{
		Rule: SourceRule{ //delete from t where col = 'condition'
			Name:       DMLHintDeleteTips,
			Desc:       plocale.DMLHintDeleteTipsDesc,
			Annotation: plocale.DMLHintDeleteTipsAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintDeleteTipsMessage,
		Func:    hintDeleteTips,
	},
	{
		Rule: SourceRule{ //SELECT BENCHMARK(10, RAND())
			Name:       DMLCheckSQLInjectionFunc,
			Desc:       plocale.DMLCheckSQLInjectionFuncDesc,
			Annotation: plocale.DMLCheckSQLInjectionFuncAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckSQLInjectionFuncMessage,
		Func:    checkSQLInjectionFunc,
	},
	{
		Rule: SourceRule{ //select col1,col2 from tbl where type!=0
			Name:       DMLCheckNotEqualSymbol,
			Desc:       plocale.DMLCheckNotEqualSymbolDesc,
			Annotation: plocale.DMLCheckNotEqualSymbolAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckNotEqualSymbolMessage,
		Func:    checkNotEqualSymbol,
	},
	{
		Rule: SourceRule{ //select col1,col2,col3 from table1 where col2 in(select col from table2)
			Name:       DMLNotRecommendSubquery,
			Desc:       plocale.DMLNotRecommendSubqueryDesc,
			Annotation: plocale.DMLNotRecommendSubqueryAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendSubqueryMessage,
		Func:    notRecommendSubquery,
	},
	{
		Rule: SourceRule{ //SELECT * FROM staff WHERE name IN (SELECT NAME FROM customer ORDER BY name LIMIT 1)
			Name:       DMLCheckSubqueryLimit,
			Desc:       plocale.DMLCheckSubqueryLimitDesc,
			Annotation: plocale.DMLCheckSubqueryLimitAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckSubqueryLimitMessage,
		Func:    checkSubqueryLimit,
	},
	{
		Rule: SourceRule{ //CREATE TABLE tbl (a int) AUTO_INCREMENT = 10;
			Name:       DDLCheckAutoIncrement,
			Desc:       plocale.DDLCheckAutoIncrementDesc,
			Annotation: plocale.DDLCheckAutoIncrementAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLCheckAutoIncrementMessage,
		Func:    checkAutoIncrement,
	},
	{
		Rule: SourceRule{ // rename table t1 to t2;
			Name:         DDLNotAllowRenaming,
			Desc:         plocale.DDLNotAllowRenamingDesc,
			Annotation:   plocale.DDLNotAllowRenamingAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLNotAllowRenamingMessage,
		Func:    ddlNotAllowRenaming,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckExplainFullIndexScan,
			Desc:         plocale.DMLCheckExplainFullIndexScanDesc,
			Annotation:   plocale.DMLCheckExplainFullIndexScanAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckExplainFullIndexScanMessage,
		Func:    checkExplain,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckLimitOffsetNum,
			Desc:         plocale.DMLCheckLimitOffsetNumDesc,
			Annotation:   plocale.DMLCheckLimitOffsetNumAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "100",
					Desc:  plocale.DMLCheckLimitOffsetNumParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckLimitOffsetNumMessage,
		Func:    checkLimitOffsetNum,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckUpdateOrDeleteHasWhere,
			Desc:         plocale.DMLCheckUpdateOrDeleteHasWhereDesc,
			Annotation:   plocale.DMLCheckUpdateOrDeleteHasWhereAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckUpdateOrDeleteHasWhereMessage,
		Func:    checkUpdateOrDeleteHasWhere,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckSortColumnLength,
			Desc:         plocale.DMLCheckSortColumnLengthDesc,
			Annotation:   plocale.DMLCheckSortColumnLengthAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "2000",
					Desc:  plocale.DMLCheckSortColumnLengthParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckSortColumnLengthMessage,
		Func:    checkSortColumnLength,
	},
	{
		Rule: SourceRule{
			Name:         AllCheckPrepareStatementPlaceholders,
			Desc:         plocale.AllCheckPrepareStatementPlaceholdersDesc,
			Annotation:   plocale.AllCheckPrepareStatementPlaceholdersAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "100",
					Desc:  plocale.AllCheckPrepareStatementPlaceholdersParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.AllCheckPrepareStatementPlaceholdersMessage,
		Func:    checkPrepareStatementPlaceholders,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckExplainExtraUsingIndexForSkipScan,
			Desc:         plocale.DMLCheckExplainExtraUsingIndexForSkipScanDesc,
			Annotation:   plocale.DMLCheckExplainExtraUsingIndexForSkipScanAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckExplainExtraUsingIndexForSkipScanMessage,
		Func:    checkExplain,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckAffectedRows,
			Desc:         plocale.DMLCheckAffectedRowsDesc,
			Annotation:   plocale.DMLCheckAffectedRowsAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "10000",
					Desc:  plocale.DMLCheckAffectedRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckAffectedRowsMessage,
		Func:    checkAffectedRows,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckSameTableJoinedMultipleTimes,
			Desc:         plocale.DMLCheckSameTableJoinedMultipleTimesDesc,
			Annotation:   plocale.DMLCheckSameTableJoinedMultipleTimesAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckSameTableJoinedMultipleTimesMessage,
		Func:    checkSameTableJoinedMultipleTimes,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckExplainUsingIndex,
			Desc:         plocale.DMLCheckExplainUsingIndexDesc,
			Annotation:   plocale.DMLCheckExplainUsingIndexAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckExplainUsingIndexMessage,
		Func:    checkExplain,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckInsertSelect,
			Desc:         plocale.DMLCheckInsertSelectDesc,
			Annotation:   plocale.DMLCheckInsertSelectAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckInsertSelectMessage,
		Func:    checkInsertSelect,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckAggregate,
			Desc:         plocale.DMLCheckAggregateDesc,
			Annotation:   plocale.DMLCheckAggregateAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLCheckAggregateMessage,
		Func:    checkAggregateFunc,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckColumnNotNULL,
			Desc:         plocale.DDLCheckColumnNotNULLDesc,
			Annotation:   plocale.DDLCheckColumnNotNULLAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: false,
		},
		Message: plocale.DDLCheckColumnNotNULLMessage,
		Func:    checkColumnNotNull,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckIndexSelectivity,
			Desc:         plocale.DMLCheckIndexSelectivityDesc,
			Annotation:   plocale.DMLCheckIndexSelectivityAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "70",
					Desc:  plocale.DMLCheckIndexSelectivityParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckIndexSelectivityMessage,
		Func:    checkIndexSelectivity,
	},
	{
		// 该规则只适用于库表元数据扫描并且需要与停用上线审核模式规则一起使用
		Rule: SourceRule{
			Name:       DDLCheckTableRows,
			Desc:       plocale.DDLCheckTableRowsDesc,
			Annotation: plocale.DDLCheckTableRowsAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeUsageSuggestion,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1000",
					Desc:  plocale.DDLCheckTableRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckTableRowsMessage,
		Func:    checkTableRows,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckCompositeIndexDistinction,
			Desc:         plocale.DDLCheckCompositeIndexDistinctionDesc,
			Annotation:   plocale.DDLCheckCompositeIndexDistinctionAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: false,
		},
		Message: plocale.DDLCheckCompositeIndexDistinctionMessage,
		Func:    checkCompositeIndexSelectivity,
	},
	{
		Rule: SourceRule{
			Name:         DDLAvoidText,
			Desc:         plocale.DDLAvoidTextDesc,
			Annotation:   plocale.DDLAvoidTextAnnotation,
			Level:        driverV2.RuleLevelNotice,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: true,
		},
		Message: plocale.DDLAvoidTextMessage,
		Func:    checkText,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckSelectRows,
			Desc:         plocale.DMLCheckSelectRowsDesc,
			Annotation:   plocale.DMLCheckSelectRowsAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "10",
					Desc:  plocale.DMLCheckSelectRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckSelectRowsMessage,
		Func:    checkSelectRows,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckScanRows,
			Desc:         plocale.DMLCheckScanRowsDesc,
			Annotation:   plocale.DMLCheckScanRowsAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "10",
					Desc:  plocale.DMLCheckScanRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckScanRowsMessage,
		Func:    checkScanRows,
	},
	{
		Rule: SourceRule{
			Name:         DMLMustUseLeftMostPrefix,
			Desc:         plocale.DMLMustUseLeftMostPrefixDesc,
			Annotation:   plocale.DMLMustUseLeftMostPrefixAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexInvalidation,
			AllowOffline: false,
		},
		Message: plocale.DMLMustUseLeftMostPrefixMessage,
		Func:    mustMatchLeftMostPrefix,
	},
	{
		Rule: SourceRule{
			Name:         DMLMustMatchLeftMostPrefix,
			Desc:         plocale.DMLMustMatchLeftMostPrefixDesc,
			Annotation:   plocale.DMLMustMatchLeftMostPrefixAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexInvalidation,
			AllowOffline: false,
		},
		Message: plocale.DMLMustMatchLeftMostPrefixMessage,
		Func:    mustMatchLeftMostPrefix,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckJoinFieldUseIndex,
			Desc:         plocale.DMLCheckJoinFieldUseIndexDesc,
			Annotation:   plocale.DMLCheckJoinFieldUseIndexAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexInvalidation,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckJoinFieldUseIndexMessage,
		Func:    checkJoinFieldUseIndex,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckJoinFieldCharacterSetAndCollation,
			Desc:         plocale.DMLCheckJoinFieldCharacterSetAndCollationDesc,
			Annotation:   plocale.DMLCheckJoinFieldCharacterSetAndCollationAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexInvalidation,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckJoinFieldCharacterSetAndCollationMessage,
		Func:    checkJoinFieldCharacterSetAndCollation,
	},
	{
		Rule: SourceRule{
			Name:         DMLCheckMathComputationOrFuncOnIndex,
			Desc:         plocale.DMLCheckMathComputationOrFuncOnIndexDesc,
			Annotation:   plocale.DMLCheckMathComputationOrFuncOnIndexAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeIndexInvalidation,
			AllowOffline: false,
		},
		Message: plocale.DMLCheckMathComputationOrFuncOnIndexMessage,
		Func:    checkMathComputationOrFuncOnIndex,
	},
	{
		Rule: SourceRule{
			Name:         DMLSQLExplainLowestLevel,
			Desc:         plocale.DMLSQLExplainLowestLevelDesc,
			Annotation:   plocale.DMLSQLExplainLowestLevelAnnotation,
			Level:        driverV2.RuleLevelWarn,
			Category:     plocale.RuleTypeDDLConvention,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "range,ref,const,eq_ref,system,NULL",
					Desc:  plocale.DMLSQLExplainLowestLevelParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DMLSQLExplainLowestLevelMessage,
		Func:    checkSQLExplainLowestLevel,
	},
	{
		Rule: SourceRule{
			Name:         DDLAvoidFullText,
			Desc:         plocale.DDLAvoidFullTextDesc,
			Annotation:   plocale.DDLAvoidFullTextAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLAvoidFullTextMessage,
		Func:    avoidFullText,
	},
	{
		Rule: SourceRule{
			Name:         DDLAvoidGeometry,
			Desc:         plocale.DDLAvoidGeometryDesc,
			Annotation:   plocale.DDLAvoidGeometryAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLAvoidGeometryMessage,
		Func:    avoidGeometry,
	},
	{
		Rule: SourceRule{
			Name:         DMLAvoidWhereEqualNull,
			Desc:         plocale.DMLAvoidWhereEqualNullDesc,
			Annotation:   plocale.DMLAvoidWhereEqualNullAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeDMLConvention,
			AllowOffline: true,
		},
		Message: plocale.DMLAvoidWhereEqualNullMessage,
		Func:    avoidWhereEqualNull,
	},
	{
		Rule: SourceRule{
			Name:         DDLAvoidEvent,
			Desc:         plocale.DDLAvoidEventDesc,
			Annotation:   plocale.DDLAvoidEventAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: true,
		},
		Message: plocale.DDLAvoidEventMessage,
		Func:    avoidEvent,
	},
	{
		Rule: SourceRule{
			Name:         DDLCheckCharLength,
			Desc:         plocale.DDLCheckCharLengthDesc,
			Annotation:   plocale.DDLCheckCharLengthAnnotation,
			Level:        driverV2.RuleLevelError,
			Category:     plocale.RuleTypeUsageSuggestion,
			AllowOffline: false,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "2000",
					Desc:  plocale.DDLCheckCharLengthParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckCharLengthMessage,
		Func:    checkCharLength,
	},
}
