@@ -14,7 +14,7 @@ module Database.PostgreSQL.PQTypes.Model.Index
1414 , uniqueIndexOnColumnWithCondition
1515 , uniqueIndexOnColumns
1616 , indexName
17- , indexNames
17+ , acceptsIndexName
1818 , IncludeColumn (unIncludeColumn )
1919 , includeColumn
2020 , sqlCreateIndexMaybeDowntime
@@ -185,34 +185,43 @@ uniqueIndexOnColumnWithCondition column whereC =
185185
186186-- | Canonical auto-generated name for an index.
187187indexName :: RawSQL () -> TableIndex -> RawSQL ()
188- indexName = indexNameImpl id
189-
190- -- | Index names accepted by 'Database.PostgreSQL.PQTypes.Checks.checkDatabase'.
191- indexNames :: RawSQL () -> TableIndex -> [RawSQL () ]
192- indexNames tname idx =
193- [ indexName tname idx
194- , -- The legacy entry, reconstructed the name that older versions produced for
195- -- keyword columns.
196- indexNameImpl (\ t -> " \" " <> t <> " \" " ) tname idx
197- ]
198-
199- indexNameImpl :: (T. Text -> T. Text ) -> RawSQL () -> TableIndex -> RawSQL ()
200- indexNameImpl preSanitize tname TableIndex {.. } =
188+ indexName = indexNameWith []
189+
190+ -- | True if @dbName@ is an acceptable index name for @idx@ on @tname@.
191+ -- Also accepts the legacy form where quoted identifiers appeared as
192+ -- @$ident$@ in the name.
193+ acceptsIndexName :: RawSQL () -> TableIndex -> RawSQL () -> Bool
194+ acceptsIndexName tname idx@ TableIndex {.. } dbName =
195+ indexNameWith mask tname idx == dbName
196+ where
197+ dbNameText = unRawSQL dbName
198+ wasQuoted ident = T. isInfixOf (" $" <> unRawSQL ident <> " $" ) dbNameText
199+ mask =
200+ map (wasQuoted . indexColumnName) idxColumns
201+ ++ map (wasQuoted . unIncludeColumn) idxInclude
202+
203+ -- | Generate an index name where each identifier (key columns first, then
204+ -- include columns) is wrapped in double quotes if the corresponding entry
205+ -- in the mask is 'True'. Positions beyond the mask default to bare.
206+ indexNameWith :: [Bool ] -> RawSQL () -> TableIndex -> RawSQL ()
207+ indexNameWith mask tname TableIndex {.. } =
201208 flip rawSQL () $
202209 T. take 63 . unRawSQL $
203210 mconcat
204211 [ if idxUnique then " unique_idx__" else " idx__"
205212 , tname
206213 , " __"
207- , mintercalate " __" $ map (asText normalize . indexColumnName) idxColumns
214+ , mintercalate " __" $ zipWith renderIdent colMask ( map indexColumnName idxColumns)
208215 , if null idxInclude
209216 then " "
210- else " $$" <> mintercalate " __" (map (asText normalize . unIncludeColumn) idxInclude)
217+ else " $$" <> mintercalate " __" (zipWith renderIdent incMask ( map unIncludeColumn idxInclude) )
211218 , maybe " " ((" __" <> ) . hashWhere) idxWhere
212219 ]
213220 where
214- asText f = flip rawSQL () . f . unRawSQL
215- normalize = sanitize . preSanitize
221+ (colMask, incMask) = splitAt (length idxColumns) (mask ++ repeat False )
222+ renderIdent quoted ident =
223+ flip rawSQL () . sanitize $
224+ if quoted then " \" " <> unRawSQL ident <> " \" " else unRawSQL ident
216225 -- See http://www.postgresql.org/docs/9.4/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS.
217226 -- Remove all unallowed characters and replace them by at most one adjacent dollar sign.
218227 sanitize = T. pack . foldr go [] . T. unpack
@@ -226,12 +235,13 @@ indexNameImpl preSanitize tname TableIndex {..} =
226235 -- hash WHERE clause and add it to index name so that indexes
227236 -- with the same columns, but different constraints can coexist
228237 hashWhere =
229- asText $
230- T. decodeUtf8
231- . B16. encode
232- . BS. take 10
233- . RIPEMD160. hash
234- . T. encodeUtf8
238+ flip rawSQL ()
239+ . T. decodeUtf8
240+ . B16. encode
241+ . BS. take 10
242+ . RIPEMD160. hash
243+ . T. encodeUtf8
244+ . unRawSQL
235245
236246-- | Create an index. Warning: if the affected table is large, this will prevent
237247-- the table from being modified during the creation. If this is not acceptable,
0 commit comments