RDFDescribeQuery is the SPARQL "DESCRIBE" query implementation.
Inheritance: RDFQuery
        /// <summary>
        /// Apply the filters of the given pattern group to its result table
        /// </summary>
        internal static void ApplyFilters(RDFDescribeQuery query, RDFPatternGroup patternGroup) {
            if (patternGroup.Patterns.Any() && patternGroup.Filters.Any()) {
                DataTable filteredTable  = query.PatternGroupResultTables[patternGroup].Clone();
                IEnumerator rowsEnum     = query.PatternGroupResultTables[patternGroup].Rows.GetEnumerator();

                //Iterate the rows of the pattern group's result table
                Boolean keepRow          = false;
                while (rowsEnum.MoveNext()) {

                    //Apply the pattern group's filters on the row
                    keepRow              = true;
                    IEnumerator<RDFFilter> filtersEnum       = patternGroup.Filters.GetEnumerator();
                    while (keepRow      && filtersEnum.MoveNext()) {
                        keepRow          = filtersEnum.Current.ApplyFilter((DataRow)rowsEnum.Current, false);
                    }

                    //If the row has passed all the filters, keep it in the filtered result table
                    if (keepRow) {
                        DataRow newRow   = filteredTable.NewRow();
                        newRow.ItemArray = ((DataRow)rowsEnum.Current).ItemArray;
                        filteredTable.Rows.Add(newRow);
                    }

                }

                //Save the result datatable
                query.PatternGroupResultTables[patternGroup] = filteredTable;
            }
        }
        /// <summary>
        /// Apply the filters of the given pattern group to its result table
        /// </summary>
        internal static void ApplyFilters(RDFDescribeQuery query, RDFPatternGroup patternGroup)
        {
            if (patternGroup.Patterns.Any() && patternGroup.Filters.Any())
            {
                DataTable   filteredTable = query.PatternGroupResultTables[patternGroup].Clone();
                IEnumerator rowsEnum      = query.PatternGroupResultTables[patternGroup].Rows.GetEnumerator();

                //Iterate the rows of the pattern group's result table
                Boolean keepRow = false;
                while (rowsEnum.MoveNext())
                {
                    //Apply the pattern group's filters on the row
                    keepRow = true;
                    IEnumerator <RDFFilter> filtersEnum = patternGroup.Filters.GetEnumerator();
                    while (keepRow && filtersEnum.MoveNext())
                    {
                        keepRow = filtersEnum.Current.ApplyFilter((DataRow)rowsEnum.Current, false);
                    }

                    //If the row has passed all the filters, keep it in the filtered result table
                    if (keepRow)
                    {
                        DataRow newRow = filteredTable.NewRow();
                        newRow.ItemArray = ((DataRow)rowsEnum.Current).ItemArray;
                        filteredTable.Rows.Add(newRow);
                    }
                }

                //Save the result datatable
                query.PatternGroupResultTables[patternGroup] = filteredTable;
            }
        }
        /// <summary>
        /// Get the result table of the given pattern group
        /// </summary>
        internal static void CombinePatterns(RDFDescribeQuery query, RDFPatternGroup patternGroup)
        {
            if (patternGroup.Patterns.Any())
            {
                //Populate pattern group result table
                DataTable patternGroupResultTable = RDFQueryEngine.CombineTables(query.PatternResultTables[patternGroup], false);

                //Add it to the list of pattern group result tables
                query.PatternGroupResultTables.Add(patternGroup, patternGroupResultTable);

                //Populate its metadata
                query.PatternGroupResultTables[patternGroup].TableName = patternGroup.ToString();
                if (!query.PatternGroupResultTables[patternGroup].ExtendedProperties.ContainsKey("IsOptional"))
                {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties.Add("IsOptional", patternGroup.IsOptional);
                }
                else
                {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties["IsOptional"] = patternGroup.IsOptional;
                }
                if (!query.PatternGroupResultTables[patternGroup].ExtendedProperties.ContainsKey("JoinAsUnion"))
                {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties.Add("JoinAsUnion", patternGroup.JoinAsUnion);
                }
                else
                {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties["JoinAsUnion"] = patternGroup.JoinAsUnion;
                }
            }
        }
        /// <summary>
        /// Apply the query modifiers to the query result table
        /// </summary>
        internal static DataTable ApplyModifiers(RDFDescribeQuery query, DataTable table)
        {
            String tablenameBak = table.TableName;

            //Apply the DISTINCT modifier
            table = new RDFDistinctModifier().ApplyModifier(table);

            //Apply the OFFSET modifier
            table = query.Modifiers.Where(m => m is RDFOffsetModifier)
                    .Aggregate(table, (current, modifier) => modifier.ApplyModifier(current));

            //Apply the LIMIT modifier
            table = query.Modifiers.Where(m => m is RDFLimitModifier)
                    .Aggregate(table, (current, modifier) => modifier.ApplyModifier(current));

            table.TableName = tablenameBak;
            return(table);
        }
        /// <summary>
        /// Get the intermediate result tables of the given pattern group
        /// </summary>
        internal static void EvaluatePatterns(RDFDescribeQuery query, RDFPatternGroup patternGroup, Object graphOrStore) {
            query.PatternResultTables[patternGroup] = new List<DataTable>();

            //Iterate over the patterns of the pattern group
            foreach (RDFPattern pattern in patternGroup.Patterns) {

                //Apply the pattern to the graph/store
                DataTable patternResultsTable       = graphOrStore is RDFGraph ? RDFQueryEngine.ApplyPattern(pattern, (RDFGraph)graphOrStore)
                                                                               : RDFQueryEngine.ApplyPattern(pattern, (RDFStore)graphOrStore);

                //Set the name and the optionality metadata of the result datatable
                patternResultsTable.TableName       = pattern.ToString();
                patternResultsTable.ExtendedProperties.Add("IsOptional", pattern.IsOptional);
                patternResultsTable.ExtendedProperties.Add("JoinAsUnion", pattern.JoinAsUnion);

                //Save the result datatable
                query.PatternResultTables[patternGroup].Add(patternResultsTable);

            }
        }
        /// <summary>
        /// Get the intermediate result tables of the given pattern group
        /// </summary>
        internal static void EvaluatePatterns(RDFDescribeQuery query, RDFPatternGroup patternGroup, Object graphOrStore)
        {
            query.PatternResultTables[patternGroup] = new List <DataTable>();

            //Iterate over the patterns of the pattern group
            foreach (RDFPattern pattern in patternGroup.Patterns)
            {
                //Apply the pattern to the graph/store
                DataTable patternResultsTable = graphOrStore is RDFGraph?RDFQueryEngine.ApplyPattern(pattern, (RDFGraph)graphOrStore)
                                                    : RDFQueryEngine.ApplyPattern(pattern, (RDFStore)graphOrStore);

                //Set the name and the optionality metadata of the result datatable
                patternResultsTable.TableName = pattern.ToString();
                patternResultsTable.ExtendedProperties.Add("IsOptional", pattern.IsOptional);
                patternResultsTable.ExtendedProperties.Add("JoinAsUnion", pattern.JoinAsUnion);

                //Save the result datatable
                query.PatternResultTables[patternGroup].Add(patternResultsTable);
            }
        }
        /// <summary>
        /// Apply the query modifiers to the query result table
        /// </summary>
        internal static DataTable ApplyModifiers(RDFDescribeQuery query, DataTable table) {
            String tablenameBak = table.TableName;

            //Apply the DISTINCT modifier
            table               = new RDFDistinctModifier().ApplyModifier(table);

            //Apply the OFFSET modifier
            table               = query.Modifiers.Where(m => m is RDFOffsetModifier)
                                                 .Aggregate(table, (current, modifier) => modifier.ApplyModifier(current));

            //Apply the LIMIT modifier
            table               = query.Modifiers.Where(m => m is RDFLimitModifier)
                                                 .Aggregate(table, (current, modifier) => modifier.ApplyModifier(current));

            table.TableName     = tablenameBak;
            return table;
        }
        /// <summary>
        /// Describes the terms of the given query with data from the given result table
        /// </summary>
        internal static DataTable DescribeTerms(RDFDescribeQuery describeQuery, Object graphOrStore, DataTable resultTable) {

            //Create the structure of the result datatable
            DataTable result                 = new DataTable("DESCRIBE_RESULTS");
            result.Columns.Add("SUBJECT",   Type.GetType("System.String"));
            result.Columns.Add("PREDICATE", Type.GetType("System.String"));
            result.Columns.Add("OBJECT",    Type.GetType("System.String"));
            result.AcceptChanges();

            //Query IS empty, so does not have pattern groups to fetch data from 
            //(we can only proceed by searching for resources in the describe terms)
            if (describeQuery.IsEmpty) {                

                //Iterate the describe terms of the query which are resources (variables are omitted, since useless)
                foreach (RDFPatternMember dt in describeQuery.DescribeTerms.Where(dterm => dterm is RDFResource)) {

                    //Search on GRAPH
                    if (graphOrStore is RDFGraph) {
                        //Search as RESOURCE (S-P-O)
                        RDFGraph desc        = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)dt)
                                                    .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)dt))
                                                        .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)dt));
                        result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                    }

                    //Search on STORE
                    else {
                        //Search as RESOURCE (S-P-O)
                        RDFMemoryStore desc  = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)dt))
                                                    .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)dt)))
                                                        .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)dt)));
                        result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                    }

                }

            }

            //Query IS NOT empty, so does have pattern groups to fetch data from
            else {

                //In case of a "Star" query, all the variables must be considered describe terms
                if (describeQuery.IsStar) {
                    describeQuery.PatternGroups.ForEach(pg => 
                        pg.Variables.ForEach(v => describeQuery.AddDescribeTerm(v))
                    );
                }

                //Iterate the describe terms of the query
                foreach (RDFPatternMember dt in describeQuery.DescribeTerms) {

                    //The describe term is a variable
                    if (dt is RDFVariable) {

                        //Process the variable
                        if(resultTable.Columns.Contains(dt.ToString())) {

                            //Iterate the results datatable's rows to retrieve terms to be described
                            IEnumerator rowsEnum           = resultTable.Rows.GetEnumerator();
                            while (rowsEnum.MoveNext()) {

                                //Row contains a value in position of the variable corresponding to the describe term
                                if (!((DataRow)rowsEnum.Current).IsNull(dt.ToString())) {
                                    
                                    //Retrieve the term to be described
                                    RDFPatternMember term  = RDFQueryUtilities.ParseRDFPatternMember(((DataRow)rowsEnum.Current)[dt.ToString()].ToString());

                                    //Search on GRAPH
                                    if (graphOrStore is RDFGraph) {
                                        //Search as RESOURCE (S-P-O)
                                        if (term is RDFResource) {
                                            RDFGraph desc  = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)term)
                                                                    .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)term))
                                                                        .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)term));
                                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                                        }
                                        //Search as LITERAL (L)
                                        else {
                                            RDFGraph desc  = ((RDFGraph)graphOrStore).SelectTriplesByLiteral((RDFLiteral)term);
                                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                                        }
                                    }

                                    //Search on STORE
                                    else {
                                        //Search as RESOURCE (S-P-O)
                                        if (term is RDFResource) {
                                            RDFMemoryStore desc  = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)term))
                                                                        .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)term)))
                                                                            .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)term)));
                                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                                        }
                                        //Search as LITERAL (L)
                                        else {
                                            RDFMemoryStore desc  = ((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesByLiteral((RDFLiteral)term));
                                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                                        }
                                    }

                                }

                            }

                        }

                    }

                    //The describe term is a resource
                    else {

                        //Search on GRAPH
                        if (graphOrStore is RDFGraph) {
                            //Search as RESOURCE (S-P-O)
                            RDFGraph desc        = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)dt)
                                                        .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)dt))
                                                            .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)dt));
                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                        }

                        //Search on STORE
                        else {
                            //Search as RESOURCE (S-P-O)
                            RDFMemoryStore desc  = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)dt))
                                                        .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)dt)))
                                                            .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)dt)));
                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                        }

                    }

                }

            }

            return result;
        }
        /// <summary>
        /// Get the result table of the given pattern group
        /// </summary>
        internal static void CombinePatterns(RDFDescribeQuery query, RDFPatternGroup patternGroup) {
            if (patternGroup.Patterns.Any()) {

                //Populate pattern group result table
                DataTable patternGroupResultTable                      = RDFQueryEngine.CombineTables(query.PatternResultTables[patternGroup], false);

                //Add it to the list of pattern group result tables
                query.PatternGroupResultTables.Add(patternGroup, patternGroupResultTable);

                //Populate its metadata
                query.PatternGroupResultTables[patternGroup].TableName = patternGroup.ToString();
                if (!query.PatternGroupResultTables[patternGroup].ExtendedProperties.ContainsKey("IsOptional")) {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties.Add("IsOptional", patternGroup.IsOptional);
                }
                else {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties["IsOptional"]  = patternGroup.IsOptional;
                }
                if (!query.PatternGroupResultTables[patternGroup].ExtendedProperties.ContainsKey("JoinAsUnion")) {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties.Add("JoinAsUnion", patternGroup.JoinAsUnion);
                }
                else {
                    query.PatternGroupResultTables[patternGroup].ExtendedProperties["JoinAsUnion"] = patternGroup.JoinAsUnion;
                }

            }
        }
Exemple #10
0
        /// <summary>
        /// Prints the string representation of a SPARQL DESCRIBE query
        /// </summary>
        internal static String PrintDescribeQuery(RDFDescribeQuery describeQuery)
        {
            StringBuilder sb = new StringBuilder();

            if (describeQuery != null)
            {
                #region PREFIXES
                if (describeQuery.Prefixes.Any())
                {
                    describeQuery.Prefixes.ForEach(pf =>
                    {
                        sb.Append("PREFIX " + pf.NamespacePrefix + ": <" + pf.NamespaceUri + ">\n");
                    });
                    sb.Append("\n");
                }
                #endregion

                #region HEADER

                #region BEGINDESCRIBE
                sb.Append("DESCRIBE");
                #endregion

                #region TERMS
                if (describeQuery.DescribeTerms.Any())
                {
                    describeQuery.DescribeTerms.ForEach(dt =>
                    {
                        sb.Append(" " + PrintPatternMember(dt, describeQuery.Prefixes));
                    });
                }
                else
                {
                    sb.Append(" *");
                }
                sb.Append("\n");
                #endregion

                #endregion

                #region BODY
                sb.Append("WHERE {\n");

                #region MEMBERS
                Boolean printingUnion = false;
                List <RDFQueryMember> evaluableQueryMembers = describeQuery.GetEvaluableQueryMembers().ToList();
                RDFQueryMember        lastQueryMbr          = evaluableQueryMembers.LastOrDefault();
                foreach (var queryMember in evaluableQueryMembers)
                {
                    #region PATTERNGROUPS
                    if (queryMember is RDFPatternGroup)
                    {
                        //Current pattern group is set as UNION with the next one
                        if (((RDFPatternGroup)queryMember).JoinAsUnion)
                        {
                            //Current pattern group IS NOT the last of the query
                            //(so UNION keyword must be appended at last)
                            if (!queryMember.Equals(lastQueryMbr))
                            {
                                //Begin a new Union block
                                if (!printingUnion)
                                {
                                    printingUnion = true;
                                    sb.Append("  {\n");
                                }
                                sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 2, true, describeQuery.Prefixes));
                                sb.Append("    UNION\n");
                            }

                            //Current pattern group IS the last of the query
                            //(so UNION keyword must not be appended at last)
                            else
                            {
                                //End the Union block
                                if (printingUnion)
                                {
                                    printingUnion = false;
                                    sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 2, true, describeQuery.Prefixes));
                                    sb.Append("  }\n");
                                }
                                else
                                {
                                    sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 0, false, describeQuery.Prefixes));
                                }
                            }
                        }

                        //Current pattern group is set as INTERSECT with the next one
                        else
                        {
                            //End the Union block
                            if (printingUnion)
                            {
                                printingUnion = false;
                                sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 2, true, describeQuery.Prefixes));
                                sb.Append("  }\n");
                            }
                            else
                            {
                                sb.Append(PrintPatternGroup((RDFPatternGroup)queryMember, 0, false, describeQuery.Prefixes));
                            }
                        }
                    }
                    #endregion

                    #region SUBQUERY
                    else if (queryMember is RDFQuery)
                    {
                        //Merge main query prefixes
                        describeQuery.Prefixes.ForEach(pf1 => {
                            if (!((RDFSelectQuery)queryMember).Prefixes.Any(pf2 => pf2.Equals(pf1)))
                            {
                                ((RDFSelectQuery)queryMember).AddPrefix(pf1);
                            }
                        });
                        //Current subquery is set as UNION with the next one
                        if (((RDFSelectQuery)queryMember).JoinAsUnion)
                        {
                            //Current subquery IS NOT the last of the query
                            //(so UNION keyword must be appended at last)
                            if (!queryMember.Equals(lastQueryMbr))
                            {
                                //Begin a new Union block
                                if (!printingUnion)
                                {
                                    printingUnion = true;
                                    sb.Append("  {\n");
                                }
                                sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, true));
                                sb.Append("    UNION\n");
                            }

                            //Current query IS the last of the query
                            //(so UNION keyword must not be appended at last)
                            else
                            {
                                //End the Union block
                                if (printingUnion)
                                {
                                    printingUnion = false;
                                    sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, true));
                                    sb.Append("  }\n");
                                }
                                else
                                {
                                    sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, false));
                                }
                            }
                        }

                        //Current query is set as INTERSECT with the next one
                        else
                        {
                            //End the Union block
                            if (printingUnion)
                            {
                                printingUnion = false;
                                sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, true));
                                sb.Append("  }\n");
                            }
                            else
                            {
                                sb.Append(PrintSelectQuery((RDFSelectQuery)queryMember, 1, false));
                            }
                        }
                    }
                    #endregion
                }
                #endregion

                sb.Append("}");
                #endregion

                #region FOOTER

                #region MODIFIERS
                List <RDFModifier> modifiers = describeQuery.GetModifiers().ToList();

                // LIMIT/OFFSET
                if (modifiers.Any(mod => mod is RDFLimitModifier || mod is RDFOffsetModifier))
                {
                    modifiers.Where(mod => mod is RDFLimitModifier)
                    .ToList()
                    .ForEach(lim => { sb.Append("\n"); sb.Append(lim); });
                    modifiers.Where(mod => mod is RDFOffsetModifier)
                    .ToList()
                    .ForEach(off => { sb.Append("\n"); sb.Append(off); });
                }
                #endregion

                #endregion
            }
            return(sb.ToString());
        }
        /// <summary>
        /// Describes the terms of the given query with data from the given result table
        /// </summary>
        internal static DataTable DescribeTerms(RDFDescribeQuery describeQuery, Object graphOrStore, DataTable resultTable)
        {
            //Create the structure of the result datatable
            DataTable result = new DataTable("DESCRIBE_RESULTS");

            result.Columns.Add("SUBJECT", Type.GetType("System.String"));
            result.Columns.Add("PREDICATE", Type.GetType("System.String"));
            result.Columns.Add("OBJECT", Type.GetType("System.String"));
            result.AcceptChanges();

            //Query IS empty, so does not have pattern groups to fetch data from
            //(we can only proceed by searching for resources in the describe terms)
            if (describeQuery.IsEmpty)
            {
                //Iterate the describe terms of the query which are resources (variables are omitted, since useless)
                foreach (RDFPatternMember dt in describeQuery.DescribeTerms.Where(dterm => dterm is RDFResource))
                {
                    //Search on GRAPH
                    if (graphOrStore is RDFGraph)
                    {
                        //Search as RESOURCE (S-P-O)
                        RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)dt)
                                        .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)dt))
                                        .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)dt));
                        result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                    }

                    //Search on STORE
                    else
                    {
                        //Search as RESOURCE (S-P-O)
                        RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)dt))
                                                                .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)dt)))
                                               .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)dt)));
                        result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                    }
                }
            }

            //Query IS NOT empty, so does have pattern groups to fetch data from
            else
            {
                //In case of a "Star" query, all the variables must be considered describe terms
                if (describeQuery.IsStar)
                {
                    describeQuery.PatternGroups.ForEach(pg =>
                                                        pg.Variables.ForEach(v => describeQuery.AddDescribeTerm(v))
                                                        );
                }

                //Iterate the describe terms of the query
                foreach (RDFPatternMember dt in describeQuery.DescribeTerms)
                {
                    //The describe term is a variable
                    if (dt is RDFVariable)
                    {
                        //Process the variable
                        if (resultTable.Columns.Contains(dt.ToString()))
                        {
                            //Iterate the results datatable's rows to retrieve terms to be described
                            IEnumerator rowsEnum = resultTable.Rows.GetEnumerator();
                            while (rowsEnum.MoveNext())
                            {
                                //Row contains a value in position of the variable corresponding to the describe term
                                if (!((DataRow)rowsEnum.Current).IsNull(dt.ToString()))
                                {
                                    //Retrieve the term to be described
                                    RDFPatternMember term = RDFQueryUtilities.ParseRDFPatternMember(((DataRow)rowsEnum.Current)[dt.ToString()].ToString());

                                    //Search on GRAPH
                                    if (graphOrStore is RDFGraph)
                                    {
                                        //Search as RESOURCE (S-P-O)
                                        if (term is RDFResource)
                                        {
                                            RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)term)
                                                            .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)term))
                                                            .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)term));
                                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                                        }
                                        //Search as LITERAL (L)
                                        else
                                        {
                                            RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesByLiteral((RDFLiteral)term);
                                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                                        }
                                    }

                                    //Search on STORE
                                    else
                                    {
                                        //Search as RESOURCE (S-P-O)
                                        if (term is RDFResource)
                                        {
                                            RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)term))
                                                                                    .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)term)))
                                                                   .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)term)));
                                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                                        }
                                        //Search as LITERAL (L)
                                        else
                                        {
                                            RDFMemoryStore desc = ((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesByLiteral((RDFLiteral)term));
                                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    //The describe term is a resource
                    else
                    {
                        //Search on GRAPH
                        if (graphOrStore is RDFGraph)
                        {
                            //Search as RESOURCE (S-P-O)
                            RDFGraph desc = ((RDFGraph)graphOrStore).SelectTriplesBySubject((RDFResource)dt)
                                            .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByPredicate((RDFResource)dt))
                                            .UnionWith(((RDFGraph)graphOrStore).SelectTriplesByObject((RDFResource)dt));
                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                        }

                        //Search on STORE
                        else
                        {
                            //Search as RESOURCE (S-P-O)
                            RDFMemoryStore desc = ((RDFMemoryStore)((RDFMemoryStore)((RDFMemoryStore)((RDFStore)graphOrStore).SelectQuadruplesBySubject((RDFResource)dt))
                                                                    .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByPredicate((RDFResource)dt)))
                                                   .UnionWith(((RDFStore)graphOrStore).SelectQuadruplesByObject((RDFResource)dt)));
                            result.Merge(desc.ToDataTable(), true, MissingSchemaAction.Add);
                        }
                    }
                }
            }

            return(result);
        }