@@ -192,9 +192,23 @@ protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null
192
192
$ buffer ['non_unique ' ] = ($ tableIndexRow ['is_unique ' ] == 0 ) ? true : false ;
193
193
}
194
194
195
- if ($ tableIndexRow ['type ' ] == 'FUNCTION-BASED NORMAL ' && !empty ($ tableIndexRow ['column_expression ' ])
195
+ // the AbstractSchemaManager only recognizes the "where" option of the first index row,
196
+ // so we take note which key holds the first row of the current index
197
+ if (is_null ($ firstIndexRowKey ) OR $ tableIndexRows [$ firstIndexRowKey ]['key_name ' ] != $ buffer ['key_name ' ]) {
198
+ // this is the first iteration or the first row of the next index
199
+ $ firstIndexRowKey = $ key ;
200
+ }
201
+
202
+ if ($ tableIndexRow ['type ' ] != 'FUNCTION-BASED NORMAL ' OR empty ($ tableIndexRow ['column_expression ' ])
196
203
) {
197
- // remove multiple an trailing whitespaces
204
+ // normal index column
205
+ $ buffer ['column_name ' ] = $ this ->getQuotedIdentifierName ($ tableIndexRow ['column_name ' ]);
206
+ $ tableIndexRow = $ buffer ;
207
+ }
208
+ else {
209
+ // this index column contains an expression
210
+
211
+ // remove multiple and trailing whitespaces
198
212
$ tableIndexRow ['column_expression ' ] = preg_replace ('!\s+! ' , ' ' , $ tableIndexRow ['column_expression ' ]);
199
213
$ tableIndexRow ['column_expression ' ] = trim ($ tableIndexRow ['column_expression ' ]);
200
214
/*
@@ -206,47 +220,51 @@ protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null
206
220
* columns appear in these expressions and you might need to adjust the order
207
221
* (this is a limitation of doctrine, not Oracle)
208
222
*/
209
- preg_match ("/ \"(.*?) \"/ " , $ tableIndexRow ['column_expression ' ],$ columnNamesInExpression );
223
+ preg_match_all (
224
+ "/ \"(.*?) \"/ " ,
225
+ $ tableIndexRow ['column_expression ' ],
226
+ $ columnNamesInExpression ,
227
+ PREG_PATTERN_ORDER
228
+ );
210
229
if (empty ($ columnNamesInExpression [1 ])) {
211
- throw new DBALException ('No column name in double quotation marks found in column expression: ' . $ tableIndexRow ['column_expression ' ]);
230
+ throw new DBALException ('No column name in double quotation marks found in column expression: '
231
+ . $ tableIndexRow ['column_expression ' ]
232
+ );
212
233
}
213
- $ expressionMapped = false ;
214
- for ($ i = 1 ; $ i <= count ($ columnNamesInExpression ); $ i ++) {
215
- $ columnName = $ this ->getQuotedIdentifierName ($ columnNamesInExpression [$ i ]);
216
- if (!isset ($ buffer ['where ' ][$ columnName ])) {
234
+ if ($ key == $ firstIndexRowKey ) {
235
+ $ buffer ['column_name ' ] = $ columnNamesInExpression [1 ][0 ];
236
+ $ buffer ['where ' ] = [$ columnNamesInExpression [1 ][0 ] => $ tableIndexRow ['column_expression ' ]];
237
+ } else {
238
+ // this is not the first row of an index and it has a column expression (stored in the "where" option)
239
+ $ expressionMapped = false ;
240
+ foreach ($ columnNamesInExpression [1 ] as $ columnName ) {
241
+ $ columnName = $ this ->getQuotedIdentifierName ($ columnName );
242
+ for ($ i = $ key - 1 ; $ i >= $ firstIndexRowKey ; $ i --) {
243
+ if ($ tableIndexRows [$ i ]['column_name ' ] == $ columnName ) {
244
+ // column name already in use
245
+ continue 2 ;
246
+ }
247
+ }
217
248
$ buffer ['column_name ' ] = $ columnName ;
218
- $ buffer ['where ' ][$ columnName ] = $ tableIndexRow ['column_expression ' ];
249
+ // make sure the where option of the first index row is set
250
+ if (!isset ($ tableIndexRows [$ firstIndexRowKey ]['where ' ])) {
251
+ $ tableIndexRows [$ firstIndexRowKey ]['where ' ] = [];
252
+ }
253
+ // add the expression to the first index row's where option
254
+ $ tableIndexRows [$ firstIndexRowKey ]['where ' ] += [$ columnName => $ tableIndexRow ['column_expression ' ]];
219
255
$ expressionMapped = true ;
220
256
break ;
221
257
}
258
+ if (!$ expressionMapped ) {
259
+ throw new DBALException ('Could not map the column expression ' . $ tableIndexRow ['column_expression ' ]
260
+ . 'to a column, because other expressions in this index have been mapped to all available column names ' );
261
+ }
222
262
}
223
- if (!$ expressionMapped ) {
224
- throw new DBALException ('Could not map the column expression ' . $ tableIndexRow ['column_expression ' ]
225
- . 'to a column, because other expressions in this index have been mapped to all available column names ' );
226
- }
227
-
228
- } else {
229
- $ buffer ['column_name ' ] = $ this ->getQuotedIdentifierName ($ tableIndexRow ['column_name ' ]);
263
+ $ tableIndexRow = $ buffer ;
230
264
}
231
265
232
- $ tableIndexRow = $ buffer ;
233
266
// $tableIndexRow is a reference, unset $buffer
234
267
unset($ buffer );
235
-
236
- // the AbstractSchemaManager only recognizes the "where" option of the first index row
237
- // so we move/merge the "where" option if we have one on another index row but the first
238
- if (is_null ($ firstIndexRowKey ) OR $ tableIndexRows [$ firstIndexRowKey ]['key_name ' ] != $ tableIndexRow ['key_name ' ]) {
239
- // this is the first iteration or the first row of the next index
240
- $ firstIndexRowKey = $ key ;
241
- } elseif (!empty ($ tableIndexRow ['where ' ])) {
242
- // this is not the first row of an index and it has a column expression (stored in the "where" option)
243
- if (!isset ($ tableIndexRows [$ firstIndexRowKey ]['where ' ])) {
244
- $ tableIndexRows [$ firstIndexRowKey ]['where ' ] = [];
245
- }
246
- $ tableIndexRows [$ firstIndexRowKey ]['where ' ] += $ tableIndexRow ['where ' ];
247
- unset($ tableIndexRow ['where ' ]);
248
- }
249
-
250
268
}
251
269
// unset reference
252
270
unset($ tableIndexRow );
0 commit comments