This is an automated email from the ASF dual-hosted git repository.

sergeykamov pushed a commit to branch NLPCRAFT-30
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/NLPCRAFT-30 by this push:
     new 1d47f2f  WIP.
1d47f2f is described below

commit 1d47f2fdfcbabed7dc929a16daaf1a018546fedf
Author: Sergey Kamov <[email protected]>
AuthorDate: Mon Apr 20 17:30:57 2020 +0300

    WIP.
---
 .../nlpcraft/examples/sql/SqlModelTest.scala       | 58 +++++++++++++++
 .../tools/sqlgen/impl/NCSqlExtractorImpl.scala     | 84 ++++++++++++++--------
 .../mgrs/nlp/enrichers/sort/NCSortEnricher.scala   | 11 +--
 .../nlp/enrichers/sort/NCEnricherSortSpec.scala    |  8 +++
 4 files changed, 128 insertions(+), 33 deletions(-)

diff --git a/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModelTest.scala 
b/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModelTest.scala
index b36169e..d82e758 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModelTest.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModelTest.scala
@@ -447,6 +447,64 @@ class SqlModelTest {
                   |  LEFT JOIN shippers ON orders.ship_via = 
shippers.shipper_id
                   |  LEFT JOIN employees ON orders.employee_id = 
employees.employee_id
                   |ORDER BY
+                  |  orders.shipped_date DESC
+                  |LIMIT
+                  |  1000
+                  """.stripMargin
+            ),
+            Case(
+                Seq(
+                    "give me the orders sorted by ship date asc"
+                ),
+                """SELECT
+                  |  orders.shipped_date,
+                  |  orders.order_id,
+                  |  orders.order_date,
+                  |  orders.required_date,
+                  |  customers.customer_id,
+                  |  customers.company_name,
+                  |  customers.contact_name,
+                  |  employees.employee_id,
+                  |  employees.last_name,
+                  |  employees.first_name,
+                  |  shippers.shipper_id,
+                  |  shippers.company_name,
+                  |  shippers.phone
+                  |FROM
+                  |  orders
+                  |  LEFT JOIN customers ON orders.customer_id = 
customers.customer_id
+                  |  LEFT JOIN shippers ON orders.ship_via = 
shippers.shipper_id
+                  |  LEFT JOIN employees ON orders.employee_id = 
employees.employee_id
+                  |ORDER BY
+                  |  orders.shipped_date ASC
+                  |LIMIT
+                  |  1000
+                  """.stripMargin
+            ),
+            Case(
+                // Default sort (nlpcraft:sort shouldn't be found)
+                Seq(
+                    "give me the orders sorted by date"
+                ),
+                """SELECT
+                  |  orders.order_date,
+                  |  orders.order_id,
+                  |  orders.required_date,
+                  |  customers.customer_id,
+                  |  customers.company_name,
+                  |  customers.contact_name,
+                  |  employees.employee_id,
+                  |  employees.last_name,
+                  |  employees.first_name,
+                  |  shippers.shipper_id,
+                  |  shippers.company_name,
+                  |  shippers.phone
+                  |FROM
+                  |  orders
+                  |  LEFT JOIN customers ON orders.customer_id = 
customers.customer_id
+                  |  LEFT JOIN shippers ON orders.ship_via = 
shippers.shipper_id
+                  |  LEFT JOIN employees ON orders.employee_id = 
employees.employee_id
+                  |ORDER BY
                   |  orders.order_id DESC
                   |LIMIT
                   |  1000
diff --git 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala
 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala
index e070119..30fd764 100644
--- 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala
+++ 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala
@@ -112,10 +112,10 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
     /**
      *
      * @param link
-     * @param typ
+     * @param element
      * @return
      */
-    private def findColumn(link: NCToken, typ: String): NCSqlColumn =
+    private def findColumn(link: NCToken, element: String): NCSqlColumn =
         findAnyColumnTokenOpt(link) match {
             // If reference is column - sort by column.
             case Some(t) ⇒ extractColumn(t)
@@ -123,7 +123,7 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
                 // If reference is table - sort by any PK column of table.
                 findAnyTableTokenOpt(link) match {
                     case Some(tab) ⇒ tab.getColumns.asScala.minBy(col ⇒ if 
(col.isPk) 0 else 1)
-                    case None ⇒ throw new NCException(s"Unexpected $typ link: 
$link")
+                    case None ⇒ throw new NCException(s"Unexpected $element 
link: $link")
                 }
         }
 
@@ -149,18 +149,44 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
      * @param tok
      * @return
      */
-    private def getLinks(
-        variant: NCVariant, tok: NCToken, idxField: String, noteField: String, 
canBeEmpty: Boolean
+    private def getOptionalLinks(variant: NCVariant, tok: NCToken, idxsField: 
String, notesField: String): Seq[NCToken] = {
+        val idxsOpt: Option[util.List[Integer]] = 
tok.metaOpt(s"${tok.getId}:$idxsField").asScala
+
+        idxsOpt match {
+            case Some(idxs) ⇒
+                val notes: util.List[String] = 
tok.metax(s"${tok.getId}:$notesField")
+
+                idxs.asScala.map(idx ⇒ {
+                    if (idx < variant.size) {
+                        val link = variant.get(idx)
+
+                        if (!notes.contains(link.getId))
+                            throw new NCException(s"Unexpected token with 
index: $idx, type: ${link.getId}")
+
+                        link
+                    }
+                    else
+                        throw new NCException(s"Token not found with index: 
$idx")
+                })
+            case None ⇒ Seq.empty
+        }
+    }
+
+    /**
+      *
+      * @param variant
+      * @param tok
+      * @return
+      */
+    private def getSingleMandatoryLinks(
+        variant: NCVariant, tok: NCToken, idxField: String, noteField: String
     ): Seq[NCToken] = {
-        val idxsOpt: Option[util.List[Integer]] = 
tok.metaOpt(s"${tok.getId}:$idxField").asScala
+        val idxs: util.List[Integer] = 
tok.metaOpt(s"${tok.getId}:$idxField").asScala.getOrElse(throw new 
NCException(s"Empty indexes for: $tok"))
 
-        if (idxsOpt.isEmpty && !canBeEmpty)
-            throw new NCException(s"Empty indexes for: $tok")
+        val note: String = tok.metax(s"${tok.getId}:$noteField")
 
-        idxsOpt.get.asScala.map(idx ⇒ {
+        idxs.asScala.map(idx ⇒
             if (idx < variant.size) {
-                val note: String = tok.metax(s"${tok.getId}:$noteField")
-
                 val link = variant.get(idx)
 
                 if (link.getId != note)
@@ -170,9 +196,10 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
             }
             else
                 throw new NCException(s"Token not found with index: $idx")
-        })
+        )
     }
 
+
     /**
      *
      * @param tok
@@ -194,7 +221,7 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
     override def extractLimit(limitTok: NCToken): NCSqlLimit = {
         checkTokenId(limitTok, "nlpcraft:limit")
         
-        val links = getLinks(variant, limitTok, "indexes", "note", canBeEmpty 
= false)
+        val links = getSingleMandatoryLinks(variant, limitTok, "indexes", 
"note")
 
         links.size match {
             case 1 ⇒
@@ -217,33 +244,34 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
     override def extractSort(sortTok: NCToken): util.List[NCSqlSort] = {
         checkTokenId(sortTok, "nlpcraft:sort")
 
-        val tables = getLinks(variant, sortTok, "subjindexes", "subjnotes", 
canBeEmpty = false).
+        val tables = getOptionalLinks(variant, sortTok, "subjindexes", 
"subjnotes").
             map(link ⇒ findTable(link, "SORT"))
 
-        val cols = getLinks(variant, sortTok, "byindexes", "bynotes", 
canBeEmpty = true).
+        val cols = getOptionalLinks(variant, sortTok, "byindexes", "bynotes").
             map(link ⇒ findColumn(link, "SORT BY"))
 
         val asc = getAsc(sortTok, "nlpcraft:sort:asc", dflt = false)
 
-        require(tables.nonEmpty)
+        require(tables.nonEmpty || cols.nonEmpty)
 
-        tables.flatMap(t ⇒ {
-            var colTabs = cols.filter(_.getTable == t.getTable)
+        def getSorts(cols: Seq[NCSqlColumn]): Seq[NCSqlSort] = cols.map(col ⇒ 
NCSqlSortImpl(col, asc))
 
-            if (colTabs.isEmpty)
-                colTabs = t.getColumns.asScala.filter(_.isPk)
+        if (tables.nonEmpty)
+            tables.flatMap(t ⇒ {
+                var colTabs = cols.filter(_.getTable == t.getTable)
 
-            if (colTabs.isEmpty)
-                colTabs = t.getColumns.asScala.take(1)
+                if (colTabs.isEmpty)
+                    colTabs = t.getColumns.asScala.filter(_.isPk)
 
-            require(colTabs.nonEmpty)
+                if (colTabs.isEmpty)
+                    colTabs = t.getColumns.asScala.take(1)
 
-            colTabs.map(col ⇒ {
-                val sort: NCSqlSort = NCSqlSortImpl(col, asc)
+                require(colTabs.nonEmpty)
 
-                sort
-            })
-        }).asJava
+                getSorts(colTabs)
+            }).asJava
+        else
+            getSorts(cols).asJava
     }
     
     /**
diff --git 
a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
 
b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
index 993dd45..e5b91ea 100644
--- 
a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
+++ 
b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
@@ -204,8 +204,8 @@ object NCSortEnricher extends NCProbeEnricher {
                     between.isEmpty || between.forall(p ⇒ p.isStopWord || 
p.stem == STEM_AND)
                 }
 
-                val minIdx = toks.dropWhile(_.isNlp).head.index
-                val maxIdx = toks.reverse.dropWhile(_.isNlp).head.index
+                val minIdx = toks.dropWhile(!_.isUser).head.index
+                val maxIdx = toks.reverse.dropWhile(!_.isUser).head.index
 
                 require(minIdx <= maxIdx)
 
@@ -229,9 +229,10 @@ object NCSortEnricher extends NCProbeEnricher {
 
         if (res.isEmpty && !nullable)
             throw new AssertionError(s"Invalid null result " +
-                s"[tokensTexts=[${toks.map(_.origText).mkString(", ")}]" +
-                s", tokensIndexes=[${toks.map(_.index).mkString(", ")}]" +
-                s", allData=[${toksNoteData.mkString(", ")}]" +
+                s"[tokensTexts=[${toks.map(_.origText).mkString("|")}]" +
+                s", notes=[${toks.flatten.map(n ⇒ 
s"${n.noteType}:[${n.tokenIndexes.mkString(",")}]").mkString("|")}]" +
+                s", tokensIndexes=[${toks.map(_.index).mkString("|")}]" +
+                s", allData=[${toksNoteData.mkString("|")}]" +
                 s"]"
             )
 
diff --git 
a/src/test/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCEnricherSortSpec.scala
 
b/src/test/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCEnricherSortSpec.scala
index 0ed4758..dd25663 100644
--- 
a/src/test/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCEnricherSortSpec.scala
+++ 
b/src/test/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCEnricherSortSpec.scala
@@ -181,6 +181,14 @@ class NCEnricherSortSpec extends NCEnricherBaseSpec {
                 nlp(text = ",", isStop = true),
                 usr(text = "B", id = "B"),
                 nlp(text = "from bottom up order", isStop = true)
+            ),
+            _ ⇒ checkExists(
+                "organize by A, B the descending",
+                srt(text = "organize by", byNotes = Seq("A", "B"), byIndexes = 
Seq(1, 3), asc = Some(false)),
+                usr(text = "A", id = "A"),
+                nlp(text = ",", isStop = true),
+                usr(text = "B", id = "B"),
+                nlp(text = "the descending", isStop = true)
             )
         )
 }

Reply via email to