You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-commits@lucene.apache.org by ry...@apache.org on 2008/07/18 23:43:42 UTC

svn commit: r678050 - in /lucene/solr/trunk/src: java/org/apache/solr/schema/IndexSchema.java test/org/apache/solr/schema/IndexSchemaTest.java

Author: ryan
Date: Fri Jul 18 14:43:42 2008
New Revision: 678050

URL: http://svn.apache.org/viewvc?rev=678050&view=rev
Log:
SOLR-619 -- refactored IndexSchema so it allows registering copy fields within SolrCoreAware.inform()

Modified:
    lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java
    lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java

Modified: lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java?rev=678050&r1=678049&r2=678050&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java Fri Jul 18 14:43:42 2008
@@ -152,15 +152,29 @@
    * <p>
    * Modifying this Map (or any item in it) will affect the real schema
    * </p>
+   * 
+   * <p>
+   * NOTE: this function is not thread safe.  However, it is safe to use within the standard
+   * <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
+   * Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
+   * </p>
    */
   public Map<String,SchemaField> getFields() { return fields; }
 
   /**
    * Provides direct access to the Map containing all Field Types
-   * in the index, keyed on fild type name.
+   * in the index, keyed on field type name.
    *
    * <p>
-   * Modifying this Map (or any item in it) will affect the real schema
+   * Modifying this Map (or any item in it) will affect the real schema.  However if you 
+   * make any modifications, be sure to call {@link IndexSchema#refreshAnalyzers()} to
+   * update the Analyzers for the registered fields.
+   * </p>
+   * 
+   * <p>
+   * NOTE: this function is not thread safe.  However, it is safe to use within the standard
+   * <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
+   * Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
    * </p>
    */
   public Map<String,FieldType> getFieldTypes() { return fieldTypes; }
@@ -287,8 +301,19 @@
     }
     return f;
   }
-
-
+  
+  /**
+   * This will re-create the Analyzers.  If you make any modifications to
+   * the Field map ({@link IndexSchema#getFields()}, this function is required
+   * to synch the internally cached field analyzers.
+   * 
+   * @since solr 1.3
+   */
+  public void refreshAnalyzers()
+  {
+    analyzer = new SolrIndexAnalyzer();
+    queryAnalyzer = new SolrQueryAnalyzer();
+  }
 
   private class SolrIndexAnalyzer extends Analyzer {
     protected final HashMap<String,Analyzer> analyzers;
@@ -567,9 +592,8 @@
     /////////////// parse out copyField commands ///////////////
     // Map<String,ArrayList<SchemaField>> cfields = new HashMap<String,ArrayList<SchemaField>>();
     // expression = "/schema/copyField";
-
-    ArrayList<DynamicCopy> dCopies = new ArrayList<DynamicCopy>();
-
+    
+    dynamicCopyFields = new DynamicCopy[] {};
     expression = "//copyField";
     nodes = (NodeList) xpath.evaluate(expression, document, XPathConstants.NODESET);
 
@@ -580,48 +604,7 @@
         String source = DOMUtil.getAttr(attrs,"source","copyField definition");
         String dest   = DOMUtil.getAttr(attrs,"dest",  "copyField definition");
 
-        boolean sourceIsPattern = isWildCard(source);
-        boolean destIsPattern   = isWildCard(dest);
-
-        log.fine("copyField source='"+source+"' dest='"+dest+"'");
-        SchemaField d = getField(dest);
-
-        if(sourceIsPattern) {
-          if( destIsPattern ) {
-            DynamicField df = null;
-            for( DynamicField dd : dynamicFields ) {
-              if( dd.regex.equals( dest ) ) {
-                df = dd;
-                break;
-              }
-            }
-            if( df == null ) {
-              throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "copyField dynamic destination must match a dynamicField." );
-            }
-            dCopies.add(new DynamicDestCopy(source, df ));
-          }
-          else {
-            dCopies.add(new DynamicCopy(source, d));
-          }
-        } 
-        else if( destIsPattern ) {
-          String msg =  "copyField only supports a dynamic destination if the source is also dynamic" ;
-          throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, msg );
-        }
-        else {
-          // retrieve the field to force an exception if it doesn't exist
-          SchemaField f = getField(source);
-
-          SchemaField[] destArr = copyFields.get(source);
-          if (destArr==null) {
-            destArr=new SchemaField[]{d};
-          } else {
-            destArr = (SchemaField[])append(destArr,d);
-          }
-          copyFields.put(source,destArr);
-
-          copyFieldTargetCounts.put(d, (copyFieldTargetCounts.containsKey(d) ? copyFieldTargetCounts.get(d) + 1 : 1));
-        }
+        registerCopyField(source, dest);
      }
       
       for (Map.Entry<SchemaField, Integer> entry : copyFieldTargetCounts.entrySet())    {
@@ -632,11 +615,6 @@
         }
       }
 
-      log.finest("Dynamic Copied Fields:" + dCopies);
-
-      // stuff it in a normal array for faster access
-      dynamicCopyFields = (DynamicCopy[])dCopies.toArray(new DynamicCopy[dCopies.size()]);
-
     } catch (SolrException e) {
       SolrConfig.severeErrors.add( e );
       throw e;
@@ -646,13 +624,86 @@
       throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Schema Parsing Failed",e,false);
     }
 
-     analyzer = new SolrIndexAnalyzer();
-     queryAnalyzer = new SolrQueryAnalyzer();
+    // create the field analyzers
+    refreshAnalyzers();
+  }
+
+  /**
+   * <p>
+   * NOTE: this function is not thread safe.  However, it is safe to use within the standard
+   * <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
+   * Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
+   * </p>
+   * 
+   * @see SolrCoreAware
+   */
+  public void registerCopyField( String source, String dest )
+  {
+    boolean sourceIsPattern = isWildCard(source);
+    boolean destIsPattern   = isWildCard(dest);
+
+    log.fine("copyField source='"+source+"' dest='"+dest+"'");
+    SchemaField d = getField(dest);
+
+    if(sourceIsPattern) {
+      if( destIsPattern ) {
+        DynamicField df = null;
+        for( DynamicField dd : dynamicFields ) {
+          if( dd.regex.equals( dest ) ) {
+            df = dd;
+            break;
+          }
+        }
+        if( df == null ) {
+          throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "copyField dynamic destination must match a dynamicField." );
+        }
+        registerDynamicCopyField(new DynamicDestCopy(source, df ));
+      }
+      else {
+        registerDynamicCopyField(new DynamicCopy(source, d));
+      }
+    } 
+    else if( destIsPattern ) {
+      String msg =  "copyField only supports a dynamic destination if the source is also dynamic" ;
+      throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, msg );
+    }
+    else {
+      // retrieve the field to force an exception if it doesn't exist
+      SchemaField f = getField(source);
+
+      SchemaField[] destArr = copyFields.get(source);
+      if (destArr==null) {
+        destArr=new SchemaField[]{d};
+      } else {
+        destArr = (SchemaField[])append(destArr,d);
+      }
+      copyFields.put(source,destArr);
+
+      copyFieldTargetCounts.put(d, (copyFieldTargetCounts.containsKey(d) ? copyFieldTargetCounts.get(d) + 1 : 1));
+    }
+  }
+  
+  private void registerDynamicCopyField( DynamicCopy dcopy )
+  {
+    if( dynamicCopyFields == null ) {
+      dynamicCopyFields = new DynamicCopy[] {dcopy};
+    }
+    else {
+      int i=0;
+      DynamicCopy[] old = dynamicCopyFields;
+      dynamicCopyFields = new DynamicCopy[dynamicCopyFields.length+1];
+      for( DynamicCopy dc : old ) {
+        dynamicCopyFields[i++] = dc;
+      }
+      dynamicCopyFields[i++] = dcopy;
+      old = null;
+    }
+    log.finest("Dynamic Copy Field:" + dcopy );
   }
 
   private static Object[] append(Object[] orig, Object item) {
     Object[] newArr = (Object[])java.lang.reflect.Array.newInstance(orig.getClass().getComponentType(), orig.length+1);
-	  System.arraycopy(orig, 0, newArr, 0, orig.length);
+    System.arraycopy(orig, 0, newArr, 0, orig.length);
     newArr[orig.length] = item;
     return newArr;
   }
@@ -864,18 +915,18 @@
 
   private DynamicField[] dynamicFields;
   public SchemaField[] getDynamicFieldPrototypes() {
-	  SchemaField[] df = new SchemaField[dynamicFields.length];
-	  for (int i=0;i<dynamicFields.length;i++) {
-		  df[i] = dynamicFields[i].prototype;
-	  }
-	  return df;
+    SchemaField[] df = new SchemaField[dynamicFields.length];
+    for (int i=0;i<dynamicFields.length;i++) {
+      df[i] = dynamicFields[i].prototype;
+    }
+    return df;
   }
 
   public String getDynamicPattern(String fieldName) {
-	 for (DynamicField df : dynamicFields) {
-		 if (df.matches(fieldName)) return df.regex;
-	 }
-	 return  null; 
+   for (DynamicField df : dynamicFields) {
+     if (df.matches(fieldName)) return df.regex;
+   }
+   return  null; 
   }
   
   /**
@@ -1024,19 +1075,19 @@
    */
 
   public SchemaField[] getCopySources(String destField) {
-	  SchemaField f = getField(destField);
-	  if (!isCopyFieldTarget(f)) {
-		  return new SchemaField[0];
-	  }
-	  List<SchemaField> sf = new ArrayList<SchemaField>();
-	  for (Map.Entry<String, SchemaField[]> cfs : copyFields.entrySet()) {
-		  for (SchemaField cf : cfs.getValue()) {
-			  if (cf.getName().equals(destField)) {
-				  sf.add(getField(cfs.getKey()));
-			  }
-		  }
-	  }
-	  return sf.toArray(new SchemaField[1]);
+    SchemaField f = getField(destField);
+    if (!isCopyFieldTarget(f)) {
+      return new SchemaField[0];
+    }
+    List<SchemaField> sf = new ArrayList<SchemaField>();
+    for (Map.Entry<String, SchemaField[]> cfs : copyFields.entrySet()) {
+      for (SchemaField cf : cfs.getValue()) {
+        if (cf.getName().equals(destField)) {
+          sf.add(getField(cfs.getKey()));
+        }
+      }
+    }
+    return sf.toArray(new SchemaField[1]);
   }
   /**
    * Get all copy fields, both the static and the dynamic ones.
@@ -1091,10 +1142,3 @@
   }
 
 }
-
-
-
-
-
-
-

Modified: lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java?rev=678050&r1=678049&r2=678050&view=diff
==============================================================================
--- lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java (original)
+++ lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java Fri Jul 18 14:43:42 2008
@@ -20,8 +20,10 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.MapSolrParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.LocalSolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequest;
@@ -90,4 +92,41 @@
     assertTrue("wrong class", similarity instanceof MockConfigurableSimilarity);
     assertEquals("is there an echo?", ((MockConfigurableSimilarity)similarity).getPassthrough());
   }
+  
+  public void testRuntimeFieldCreation()
+  {
+    // any field manipulation needs to happen when you know the core will not 
+    // be accepting any requests.  Typically this is done within the inform() 
+    // method.  Since this is a single threaded test, we can change the fields
+    // willi-nilly
+
+    SolrCore core = h.getCore();
+    IndexSchema schema = core.getSchema();
+    final String fieldName = "runtimefield";
+    SchemaField sf = new SchemaField( fieldName, schema.getFieldTypes().get( "string" ) );
+    schema.getFields().put( fieldName, sf );
+    
+    // also register a new copy field (from our new field)
+    schema.registerCopyField( fieldName, "dynamic_runtime" );
+    schema.refreshAnalyzers();
+    
+    assertU(adoc("id", "10", "title", "test", fieldName, "aaa"));
+    assertU(commit());
+
+    SolrQuery query = new SolrQuery( fieldName+":aaa" );
+    query.set( "indent", "true" );
+    SolrQueryRequest req = new LocalSolrQueryRequest( core, query );
+    
+    assertQ("Make sure they got in", req
+            ,"//*[@numFound='1']"
+            ,"//result/doc[1]/int[@name='id'][.='10']"
+            );
+    
+    // Check to see if our copy field made it out safely
+    query.setQuery( "dynamic_runtime:aaa" );
+    assertQ("Make sure they got in", req
+            ,"//*[@numFound='1']"
+            ,"//result/doc[1]/int[@name='id'][.='10']"
+            );
+  }
 }



Re: svn commit: r678050 - in /lucene/solr/trunk/src: java/org/apache/solr/schema/IndexSchema.java test/org/apache/solr/schema/IndexSchemaTest.java

Posted by Noble Paul നോബിള്‍ नोब्ळ् <no...@gmail.com>.
The private void registerDynamicCopyField can use the code which I
gave . It is cleaner to use System.arrayCopy() rather than doing a
manual copy

2008/7/19  <ry...@apache.org>:
> Author: ryan
> Date: Fri Jul 18 14:43:42 2008
> New Revision: 678050
>
> URL: http://svn.apache.org/viewvc?rev=678050&view=rev
> Log:
> SOLR-619 -- refactored IndexSchema so it allows registering copy fields within SolrCoreAware.inform()
>
> Modified:
>    lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java
>    lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java
>
> Modified: lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java?rev=678050&r1=678049&r2=678050&view=diff
> ==============================================================================
> --- lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java (original)
> +++ lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java Fri Jul 18 14:43:42 2008
> @@ -152,15 +152,29 @@
>    * <p>
>    * Modifying this Map (or any item in it) will affect the real schema
>    * </p>
> +   *
> +   * <p>
> +   * NOTE: this function is not thread safe.  However, it is safe to use within the standard
> +   * <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
> +   * Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
> +   * </p>
>    */
>   public Map<String,SchemaField> getFields() { return fields; }
>
>   /**
>    * Provides direct access to the Map containing all Field Types
> -   * in the index, keyed on fild type name.
> +   * in the index, keyed on field type name.
>    *
>    * <p>
> -   * Modifying this Map (or any item in it) will affect the real schema
> +   * Modifying this Map (or any item in it) will affect the real schema.  However if you
> +   * make any modifications, be sure to call {@link IndexSchema#refreshAnalyzers()} to
> +   * update the Analyzers for the registered fields.
> +   * </p>
> +   *
> +   * <p>
> +   * NOTE: this function is not thread safe.  However, it is safe to use within the standard
> +   * <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
> +   * Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
>    * </p>
>    */
>   public Map<String,FieldType> getFieldTypes() { return fieldTypes; }
> @@ -287,8 +301,19 @@
>     }
>     return f;
>   }
> -
> -
> +
> +  /**
> +   * This will re-create the Analyzers.  If you make any modifications to
> +   * the Field map ({@link IndexSchema#getFields()}, this function is required
> +   * to synch the internally cached field analyzers.
> +   *
> +   * @since solr 1.3
> +   */
> +  public void refreshAnalyzers()
> +  {
> +    analyzer = new SolrIndexAnalyzer();
> +    queryAnalyzer = new SolrQueryAnalyzer();
> +  }
>
>   private class SolrIndexAnalyzer extends Analyzer {
>     protected final HashMap<String,Analyzer> analyzers;
> @@ -567,9 +592,8 @@
>     /////////////// parse out copyField commands ///////////////
>     // Map<String,ArrayList<SchemaField>> cfields = new HashMap<String,ArrayList<SchemaField>>();
>     // expression = "/schema/copyField";
> -
> -    ArrayList<DynamicCopy> dCopies = new ArrayList<DynamicCopy>();
> -
> +
> +    dynamicCopyFields = new DynamicCopy[] {};
>     expression = "//copyField";
>     nodes = (NodeList) xpath.evaluate(expression, document, XPathConstants.NODESET);
>
> @@ -580,48 +604,7 @@
>         String source = DOMUtil.getAttr(attrs,"source","copyField definition");
>         String dest   = DOMUtil.getAttr(attrs,"dest",  "copyField definition");
>
> -        boolean sourceIsPattern = isWildCard(source);
> -        boolean destIsPattern   = isWildCard(dest);
> -
> -        log.fine("copyField source='"+source+"' dest='"+dest+"'");
> -        SchemaField d = getField(dest);
> -
> -        if(sourceIsPattern) {
> -          if( destIsPattern ) {
> -            DynamicField df = null;
> -            for( DynamicField dd : dynamicFields ) {
> -              if( dd.regex.equals( dest ) ) {
> -                df = dd;
> -                break;
> -              }
> -            }
> -            if( df == null ) {
> -              throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "copyField dynamic destination must match a dynamicField." );
> -            }
> -            dCopies.add(new DynamicDestCopy(source, df ));
> -          }
> -          else {
> -            dCopies.add(new DynamicCopy(source, d));
> -          }
> -        }
> -        else if( destIsPattern ) {
> -          String msg =  "copyField only supports a dynamic destination if the source is also dynamic" ;
> -          throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, msg );
> -        }
> -        else {
> -          // retrieve the field to force an exception if it doesn't exist
> -          SchemaField f = getField(source);
> -
> -          SchemaField[] destArr = copyFields.get(source);
> -          if (destArr==null) {
> -            destArr=new SchemaField[]{d};
> -          } else {
> -            destArr = (SchemaField[])append(destArr,d);
> -          }
> -          copyFields.put(source,destArr);
> -
> -          copyFieldTargetCounts.put(d, (copyFieldTargetCounts.containsKey(d) ? copyFieldTargetCounts.get(d) + 1 : 1));
> -        }
> +        registerCopyField(source, dest);
>      }
>
>       for (Map.Entry<SchemaField, Integer> entry : copyFieldTargetCounts.entrySet())    {
> @@ -632,11 +615,6 @@
>         }
>       }
>
> -      log.finest("Dynamic Copied Fields:" + dCopies);
> -
> -      // stuff it in a normal array for faster access
> -      dynamicCopyFields = (DynamicCopy[])dCopies.toArray(new DynamicCopy[dCopies.size()]);
> -
>     } catch (SolrException e) {
>       SolrConfig.severeErrors.add( e );
>       throw e;
> @@ -646,13 +624,86 @@
>       throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Schema Parsing Failed",e,false);
>     }
>
> -     analyzer = new SolrIndexAnalyzer();
> -     queryAnalyzer = new SolrQueryAnalyzer();
> +    // create the field analyzers
> +    refreshAnalyzers();
> +  }
> +
> +  /**
> +   * <p>
> +   * NOTE: this function is not thread safe.  However, it is safe to use within the standard
> +   * <code>inform( SolrCore core )</code> function for <code>SolrCoreAware</code> classes.
> +   * Outside <code>inform</code>, this could potentially throw a ConcurrentModificationException
> +   * </p>
> +   *
> +   * @see SolrCoreAware
> +   */
> +  public void registerCopyField( String source, String dest )
> +  {
> +    boolean sourceIsPattern = isWildCard(source);
> +    boolean destIsPattern   = isWildCard(dest);
> +
> +    log.fine("copyField source='"+source+"' dest='"+dest+"'");
> +    SchemaField d = getField(dest);
> +
> +    if(sourceIsPattern) {
> +      if( destIsPattern ) {
> +        DynamicField df = null;
> +        for( DynamicField dd : dynamicFields ) {
> +          if( dd.regex.equals( dest ) ) {
> +            df = dd;
> +            break;
> +          }
> +        }
> +        if( df == null ) {
> +          throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "copyField dynamic destination must match a dynamicField." );
> +        }
> +        registerDynamicCopyField(new DynamicDestCopy(source, df ));
> +      }
> +      else {
> +        registerDynamicCopyField(new DynamicCopy(source, d));
> +      }
> +    }
> +    else if( destIsPattern ) {
> +      String msg =  "copyField only supports a dynamic destination if the source is also dynamic" ;
> +      throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, msg );
> +    }
> +    else {
> +      // retrieve the field to force an exception if it doesn't exist
> +      SchemaField f = getField(source);
> +
> +      SchemaField[] destArr = copyFields.get(source);
> +      if (destArr==null) {
> +        destArr=new SchemaField[]{d};
> +      } else {
> +        destArr = (SchemaField[])append(destArr,d);
> +      }
> +      copyFields.put(source,destArr);
> +
> +      copyFieldTargetCounts.put(d, (copyFieldTargetCounts.containsKey(d) ? copyFieldTargetCounts.get(d) + 1 : 1));
> +    }
> +  }
> +
> +  private void registerDynamicCopyField( DynamicCopy dcopy )
> +  {
> +    if( dynamicCopyFields == null ) {
> +      dynamicCopyFields = new DynamicCopy[] {dcopy};
> +    }
> +    else {
> +      int i=0;
> +      DynamicCopy[] old = dynamicCopyFields;
> +      dynamicCopyFields = new DynamicCopy[dynamicCopyFields.length+1];
> +      for( DynamicCopy dc : old ) {
> +        dynamicCopyFields[i++] = dc;
> +      }
> +      dynamicCopyFields[i++] = dcopy;
> +      old = null;
> +    }
> +    log.finest("Dynamic Copy Field:" + dcopy );
>   }
>
>   private static Object[] append(Object[] orig, Object item) {
>     Object[] newArr = (Object[])java.lang.reflect.Array.newInstance(orig.getClass().getComponentType(), orig.length+1);
> -         System.arraycopy(orig, 0, newArr, 0, orig.length);
> +    System.arraycopy(orig, 0, newArr, 0, orig.length);
>     newArr[orig.length] = item;
>     return newArr;
>   }
> @@ -864,18 +915,18 @@
>
>   private DynamicField[] dynamicFields;
>   public SchemaField[] getDynamicFieldPrototypes() {
> -         SchemaField[] df = new SchemaField[dynamicFields.length];
> -         for (int i=0;i<dynamicFields.length;i++) {
> -                 df[i] = dynamicFields[i].prototype;
> -         }
> -         return df;
> +    SchemaField[] df = new SchemaField[dynamicFields.length];
> +    for (int i=0;i<dynamicFields.length;i++) {
> +      df[i] = dynamicFields[i].prototype;
> +    }
> +    return df;
>   }
>
>   public String getDynamicPattern(String fieldName) {
> -        for (DynamicField df : dynamicFields) {
> -                if (df.matches(fieldName)) return df.regex;
> -        }
> -        return  null;
> +   for (DynamicField df : dynamicFields) {
> +     if (df.matches(fieldName)) return df.regex;
> +   }
> +   return  null;
>   }
>
>   /**
> @@ -1024,19 +1075,19 @@
>    */
>
>   public SchemaField[] getCopySources(String destField) {
> -         SchemaField f = getField(destField);
> -         if (!isCopyFieldTarget(f)) {
> -                 return new SchemaField[0];
> -         }
> -         List<SchemaField> sf = new ArrayList<SchemaField>();
> -         for (Map.Entry<String, SchemaField[]> cfs : copyFields.entrySet()) {
> -                 for (SchemaField cf : cfs.getValue()) {
> -                         if (cf.getName().equals(destField)) {
> -                                 sf.add(getField(cfs.getKey()));
> -                         }
> -                 }
> -         }
> -         return sf.toArray(new SchemaField[1]);
> +    SchemaField f = getField(destField);
> +    if (!isCopyFieldTarget(f)) {
> +      return new SchemaField[0];
> +    }
> +    List<SchemaField> sf = new ArrayList<SchemaField>();
> +    for (Map.Entry<String, SchemaField[]> cfs : copyFields.entrySet()) {
> +      for (SchemaField cf : cfs.getValue()) {
> +        if (cf.getName().equals(destField)) {
> +          sf.add(getField(cfs.getKey()));
> +        }
> +      }
> +    }
> +    return sf.toArray(new SchemaField[1]);
>   }
>   /**
>    * Get all copy fields, both the static and the dynamic ones.
> @@ -1091,10 +1142,3 @@
>   }
>
>  }
> -
> -
> -
> -
> -
> -
> -
>
> Modified: lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java
> URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java?rev=678050&r1=678049&r2=678050&view=diff
> ==============================================================================
> --- lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java (original)
> +++ lucene/solr/trunk/src/test/org/apache/solr/schema/IndexSchemaTest.java Fri Jul 18 14:43:42 2008
> @@ -20,8 +20,10 @@
>  import java.util.HashMap;
>  import java.util.Map;
>
> +import org.apache.solr.client.solrj.SolrQuery;
>  import org.apache.solr.common.params.CommonParams;
>  import org.apache.solr.common.params.MapSolrParams;
> +import org.apache.solr.common.params.ModifiableSolrParams;
>  import org.apache.solr.core.SolrCore;
>  import org.apache.solr.request.LocalSolrQueryRequest;
>  import org.apache.solr.request.SolrQueryRequest;
> @@ -90,4 +92,41 @@
>     assertTrue("wrong class", similarity instanceof MockConfigurableSimilarity);
>     assertEquals("is there an echo?", ((MockConfigurableSimilarity)similarity).getPassthrough());
>   }
> +
> +  public void testRuntimeFieldCreation()
> +  {
> +    // any field manipulation needs to happen when you know the core will not
> +    // be accepting any requests.  Typically this is done within the inform()
> +    // method.  Since this is a single threaded test, we can change the fields
> +    // willi-nilly
> +
> +    SolrCore core = h.getCore();
> +    IndexSchema schema = core.getSchema();
> +    final String fieldName = "runtimefield";
> +    SchemaField sf = new SchemaField( fieldName, schema.getFieldTypes().get( "string" ) );
> +    schema.getFields().put( fieldName, sf );
> +
> +    // also register a new copy field (from our new field)
> +    schema.registerCopyField( fieldName, "dynamic_runtime" );
> +    schema.refreshAnalyzers();
> +
> +    assertU(adoc("id", "10", "title", "test", fieldName, "aaa"));
> +    assertU(commit());
> +
> +    SolrQuery query = new SolrQuery( fieldName+":aaa" );
> +    query.set( "indent", "true" );
> +    SolrQueryRequest req = new LocalSolrQueryRequest( core, query );
> +
> +    assertQ("Make sure they got in", req
> +            ,"//*[@numFound='1']"
> +            ,"//result/doc[1]/int[@name='id'][.='10']"
> +            );
> +
> +    // Check to see if our copy field made it out safely
> +    query.setQuery( "dynamic_runtime:aaa" );
> +    assertQ("Make sure they got in", req
> +            ,"//*[@numFound='1']"
> +            ,"//result/doc[1]/int[@name='id'][.='10']"
> +            );
> +  }
>  }
>
>
>



-- 
--Noble Paul