You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by dl...@apache.org on 2021/12/02 01:00:38 UTC

[asterixdb] branch master updated: [ASTERIXDB-2992][FUN] Integer type constructors should accept non-integers

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

dlych pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 8abcf84  [ASTERIXDB-2992][FUN] Integer type constructors should accept non-integers
8abcf84 is described below

commit 8abcf84df9e1dcb94abf978589204de1ca0684da
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Tue Nov 30 20:34:16 2021 -0800

    [ASTERIXDB-2992][FUN] Integer type constructors should accept non-integers
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    - Make integer type constructors accept non-integer
      numbers and convert them to integers
    - Add testcases
    
    Change-Id: Iba39eaa04a70cdb6cc50f2399263459197af2820
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/14283
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
---
 .../constructor/int_01/int_01.3.query.sqlpp        | 19 +++++-
 .../constructor/int_01/int_01.4.query.sqlpp        | 18 +++++-
 .../constructor/int_01/int_01.5.query.sqlpp        | 17 +++++-
 .../constructor/int_01/int_01.6.query.sqlpp        | 16 ++++-
 .../results/constructor/int_01/int_01.1.adm        | 16 +++++
 .../results/constructor/int_01/int_01.2.adm        | 15 +++++
 .../results/constructor/int_01/int_01.3.adm        | 14 +++++
 .../results/constructor/int_01/int_01.4.adm        | 13 ++++
 .../ddl/index-cast-null/index-cast-null.003.adm    |  6 +-
 .../ddl/index-cast-null/index-cast-null.005.adm    |  6 +-
 .../ddl/index-cast-null/index-cast-null.006.adm    |  2 +-
 .../ddl/index-cast-null/index-cast-null.009.adm    |  6 +-
 .../ddl/index-cast-null/index-cast-null.011.adm    |  6 +-
 .../ddl/index-cast-null/index-cast-null.012.adm    |  2 +-
 .../constructor/int_01/int_01.3.ast                | 26 ++++++++
 .../constructor/int_01/int_01.4.ast                | 23 ++++++++
 .../constructor/int_01/int_01.5.ast                | 20 +++++++
 .../constructor/int_01/int_01.6.ast                | 17 ++++++
 .../external/parser/AbstractDataParser.java        |  2 +-
 .../runtime/evaluators/common/NumberUtils.java     | 62 +++++++++++++++++--
 .../AbstractInt16ConstructorEvaluator.java         | 41 +++++++------
 .../AbstractInt32ConstructorEvaluator.java         | 41 +++++++------
 .../AbstractInt64ConstructorEvaluator.java         | 41 +++++++------
 .../AbstractInt8ConstructorEvaluator.java          | 33 +++++++----
 .../AbstractIntConstructorEvaluator.java           | 69 ++++++++++++++++++++++
 .../evaluators/functions/ToNumberDescriptor.java   |  6 +-
 26 files changed, 434 insertions(+), 103 deletions(-)

diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.3.query.sqlpp
index c394848..4ac431a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.3.query.sqlpp
@@ -28,7 +28,24 @@ test = [
   float(1.25),
   double(2.25),
   false,
-  true
+  true,
+  '80.25',
+  '80.5',
+  '80.75',
+  '-80.25',
+  '-80.5',
+  '-80.75',
+  '8.125e1',
+  '-812.5e-1',
+  /* out of range */
+  int16(999),
+  int32(999),
+  int64(999),
+  float(999),
+  double(999),
+  'INF',
+  '-INF',
+  'NaN'
 ],
 testNull = [
   null,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.4.query.sqlpp
index c9e7459..5c4363a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.4.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.4.query.sqlpp
@@ -28,7 +28,23 @@ test = [
   float(1.25),
   double(2.25),
   false,
-  true
+  true,
+  '160.25',
+  '160.5',
+  '160.75',
+  '-160.25',
+  '-160.5',
+  '-160.75',
+  '16.125e1',
+  '-1612.5e-1',
+  /* out of range */
+  int32(99999),
+  int64(99999),
+  float(99999),
+  double(99999),
+  'INF',
+  '-INF',
+  'NaN'
 ],
 testNull = [
   null,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.5.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.5.query.sqlpp
index a097052..d0b9f33 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.5.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.5.query.sqlpp
@@ -28,7 +28,22 @@ test = [
   float(1.25),
   double(2.25),
   false,
-  true
+  true,
+  '320.25',
+  '320.5',
+  '320.75',
+  '-320.25',
+  '-320.5',
+  '-320.75',
+  '32.125e1',
+  '-3212.5e-1',
+  /* out of range */
+  int64(9999999999),
+  float(9999999999),
+  double(9999999999),
+  'INF',
+  '-INF',
+  'NaN'
 ],
 testNull = [
   null,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.6.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.6.query.sqlpp
index 4395da1..af0919f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.6.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/constructor/int_01/int_01.6.query.sqlpp
@@ -29,7 +29,21 @@ test = [
   float(1.25),
   double(2.25),
   false,
-  true
+  true,
+  '640.25',
+  '640.5',
+  '640.75',
+  '-640.25',
+  '-640.5',
+  '-640.75',
+  '64.125e1',
+  '-6412.5e-1',
+  /* out of range */
+  float('1e100'),
+  double('1e100'),
+  'INF',
+  '-INF',
+  'NaN'
 ],
 testNull = [
   null,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.1.adm
index 23d680c..c471941 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.1.adm
@@ -8,6 +8,22 @@
 { "g": 0, "i": 7, "actual": 2 }
 { "g": 0, "i": 8, "actual": 0 }
 { "g": 0, "i": 9, "actual": 1 }
+{ "g": 0, "i": 10, "actual": 80 }
+{ "g": 0, "i": 11, "actual": 80 }
+{ "g": 0, "i": 12, "actual": 80 }
+{ "g": 0, "i": 13, "actual": -81 }
+{ "g": 0, "i": 14, "actual": -81 }
+{ "g": 0, "i": 15, "actual": -81 }
+{ "g": 0, "i": 16, "actual": 81 }
+{ "g": 0, "i": 17, "actual": -82 }
+{ "g": 0, "i": 18, "actual": 127 }
+{ "g": 0, "i": 19, "actual": 127 }
+{ "g": 0, "i": 20, "actual": 127 }
+{ "g": 0, "i": 21, "actual": 127 }
+{ "g": 0, "i": 22, "actual": 127 }
+{ "g": 0, "i": 23, "actual": 127 }
+{ "g": 0, "i": 24, "actual": -128 }
+{ "g": 0, "i": 25, "actual": 0 }
 { "g": 1, "i": 0, "expected": null, "actual": null }
 { "g": 1, "i": 1, "expected": null, "actual": null }
 { "g": 1, "i": 2, "expected": null, "actual": null }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.2.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.2.adm
index 9266743..2464aa4 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.2.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.2.adm
@@ -8,6 +8,21 @@
 { "g": 0, "i": 7, "actual": 2 }
 { "g": 0, "i": 8, "actual": 0 }
 { "g": 0, "i": 9, "actual": 1 }
+{ "g": 0, "i": 10, "actual": 160 }
+{ "g": 0, "i": 11, "actual": 160 }
+{ "g": 0, "i": 12, "actual": 160 }
+{ "g": 0, "i": 13, "actual": -161 }
+{ "g": 0, "i": 14, "actual": -161 }
+{ "g": 0, "i": 15, "actual": -161 }
+{ "g": 0, "i": 16, "actual": 161 }
+{ "g": 0, "i": 17, "actual": -162 }
+{ "g": 0, "i": 18, "actual": 32767 }
+{ "g": 0, "i": 19, "actual": 32767 }
+{ "g": 0, "i": 20, "actual": 32767 }
+{ "g": 0, "i": 21, "actual": 32767 }
+{ "g": 0, "i": 22, "actual": 32767 }
+{ "g": 0, "i": 23, "actual": -32768 }
+{ "g": 0, "i": 24, "actual": 0 }
 { "g": 1, "i": 0, "expected": null, "actual": null }
 { "g": 1, "i": 1, "expected": null, "actual": null }
 { "g": 1, "i": 2, "expected": null, "actual": null }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.3.adm
index 94f478b..282733d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.3.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.3.adm
@@ -8,6 +8,20 @@
 { "g": 0, "i": 7, "actual": 2 }
 { "g": 0, "i": 8, "actual": 0 }
 { "g": 0, "i": 9, "actual": 1 }
+{ "g": 0, "i": 10, "actual": 320 }
+{ "g": 0, "i": 11, "actual": 320 }
+{ "g": 0, "i": 12, "actual": 320 }
+{ "g": 0, "i": 13, "actual": -321 }
+{ "g": 0, "i": 14, "actual": -321 }
+{ "g": 0, "i": 15, "actual": -321 }
+{ "g": 0, "i": 16, "actual": 321 }
+{ "g": 0, "i": 17, "actual": -322 }
+{ "g": 0, "i": 18, "actual": 2147483647 }
+{ "g": 0, "i": 19, "actual": 2147483647 }
+{ "g": 0, "i": 20, "actual": 2147483647 }
+{ "g": 0, "i": 21, "actual": 2147483647 }
+{ "g": 0, "i": 22, "actual": -2147483648 }
+{ "g": 0, "i": 23, "actual": 0 }
 { "g": 1, "i": 0, "expected": null, "actual": null }
 { "g": 1, "i": 1, "expected": null, "actual": null }
 { "g": 1, "i": 2, "expected": null, "actual": null }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.4.adm
index fa67c50..dccc6fd 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.4.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/constructor/int_01/int_01.4.adm
@@ -9,6 +9,19 @@
 { "g": 0, "i": 8, "actual": 2 }
 { "g": 0, "i": 9, "actual": 0 }
 { "g": 0, "i": 10, "actual": 1 }
+{ "g": 0, "i": 11, "actual": 640 }
+{ "g": 0, "i": 12, "actual": 640 }
+{ "g": 0, "i": 13, "actual": 640 }
+{ "g": 0, "i": 14, "actual": -641 }
+{ "g": 0, "i": 15, "actual": -641 }
+{ "g": 0, "i": 16, "actual": -641 }
+{ "g": 0, "i": 17, "actual": 641 }
+{ "g": 0, "i": 18, "actual": -642 }
+{ "g": 0, "i": 19, "actual": 9223372036854775807 }
+{ "g": 0, "i": 20, "actual": 9223372036854775807 }
+{ "g": 0, "i": 21, "actual": 9223372036854775807 }
+{ "g": 0, "i": 22, "actual": -9223372036854775808 }
+{ "g": 0, "i": 23, "actual": 0 }
 { "g": 1, "i": 0, "expected": null, "actual": null }
 { "g": 1, "i": 1, "expected": null, "actual": null }
 { "g": 1, "i": 2, "expected": null, "actual": null }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.003.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.003.adm
index 07490c7..e2aa8c8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.003.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.003.adm
@@ -1,9 +1,9 @@
 { "values": [ null, null, 9 ] }
 { "values": [ null, "1", 1 ] }
-{ "values": [ null, "3", 3 ] }
 { "values": [ null, "4", 4 ] }
 { "values": [ null, "5", 5 ] }
-{ "values": [ null, "7", 7 ] }
 { "values": [ null, "8", 8 ] }
 { "values": [ 2, "2", 2 ] }
-{ "values": [ 6, "6", 6 ] }
\ No newline at end of file
+{ "values": [ 3, "3", 3 ] }
+{ "values": [ 6, "6", 6 ] }
+{ "values": [ 7, "7", 7 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.005.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.005.adm
index 5ae6457..799cdcc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.005.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.005.adm
@@ -1,9 +1,9 @@
 { "values": [ null, 1 ] }
-{ "values": [ null, 3 ] }
 { "values": [ null, 4 ] }
 { "values": [ null, 5 ] }
-{ "values": [ null, 7 ] }
 { "values": [ null, 8 ] }
 { "values": [ null, 9 ] }
 { "values": [ 2, 2 ] }
-{ "values": [ 6, 6 ] }
\ No newline at end of file
+{ "values": [ 3, 3 ] }
+{ "values": [ 6, 6 ] }
+{ "values": [ 7, 7 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.006.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.006.adm
index 1c266b2..4ca6341 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.006.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.006.adm
@@ -1,4 +1,3 @@
-{ "values": [ null, 4 ] }
 { "values": [ null, 5 ] }
 { "values": [ null, 8 ] }
 { "values": [ null, 9 ] }
@@ -6,4 +5,5 @@
 { "values": [ 1, 1 ] }
 { "values": [ 1, 2 ] }
 { "values": [ 1, 3 ] }
+{ "values": [ 1, 4 ] }
 { "values": [ 1, 6 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.009.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.009.adm
index 07490c7..e2aa8c8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.009.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.009.adm
@@ -1,9 +1,9 @@
 { "values": [ null, null, 9 ] }
 { "values": [ null, "1", 1 ] }
-{ "values": [ null, "3", 3 ] }
 { "values": [ null, "4", 4 ] }
 { "values": [ null, "5", 5 ] }
-{ "values": [ null, "7", 7 ] }
 { "values": [ null, "8", 8 ] }
 { "values": [ 2, "2", 2 ] }
-{ "values": [ 6, "6", 6 ] }
\ No newline at end of file
+{ "values": [ 3, "3", 3 ] }
+{ "values": [ 6, "6", 6 ] }
+{ "values": [ 7, "7", 7 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.011.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.011.adm
index 5ae6457..799cdcc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.011.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.011.adm
@@ -1,9 +1,9 @@
 { "values": [ null, 1 ] }
-{ "values": [ null, 3 ] }
 { "values": [ null, 4 ] }
 { "values": [ null, 5 ] }
-{ "values": [ null, 7 ] }
 { "values": [ null, 8 ] }
 { "values": [ null, 9 ] }
 { "values": [ 2, 2 ] }
-{ "values": [ 6, 6 ] }
\ No newline at end of file
+{ "values": [ 3, 3 ] }
+{ "values": [ 6, 6 ] }
+{ "values": [ 7, 7 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.012.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.012.adm
index 1c266b2..4ca6341 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.012.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/ddl/index-cast-null/index-cast-null.012.adm
@@ -1,4 +1,3 @@
-{ "values": [ null, 4 ] }
 { "values": [ null, 5 ] }
 { "values": [ null, 8 ] }
 { "values": [ null, 9 ] }
@@ -6,4 +5,5 @@
 { "values": [ 1, 1 ] }
 { "values": [ 1, 2 ] }
 { "values": [ 1, 3 ] }
+{ "values": [ 1, 4 ] }
 { "values": [ 1, 6 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.3.ast
index 7e5840a..c84907e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.3.ast
@@ -24,6 +24,32 @@ Let Variable [ Name=$test ]
     ]
     LiteralExpr [FALSE]
     LiteralExpr [TRUE]
+    LiteralExpr [STRING] [80.25]
+    LiteralExpr [STRING] [80.5]
+    LiteralExpr [STRING] [80.75]
+    LiteralExpr [STRING] [-80.25]
+    LiteralExpr [STRING] [-80.5]
+    LiteralExpr [STRING] [-80.75]
+    LiteralExpr [STRING] [8.125e1]
+    LiteralExpr [STRING] [-812.5e-1]
+    FunctionCall asterix.int16@1[
+      LiteralExpr [LONG] [999]
+    ]
+    FunctionCall asterix.int32@1[
+      LiteralExpr [LONG] [999]
+    ]
+    FunctionCall asterix.int64@1[
+      LiteralExpr [LONG] [999]
+    ]
+    FunctionCall asterix.float@1[
+      LiteralExpr [LONG] [999]
+    ]
+    FunctionCall asterix.double@1[
+      LiteralExpr [LONG] [999]
+    ]
+    LiteralExpr [STRING] [INF]
+    LiteralExpr [STRING] [-INF]
+    LiteralExpr [STRING] [NaN]
   ]
 Let Variable [ Name=$testNull ]
   :=
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.4.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.4.ast
index c901269..f0ae023 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.4.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.4.ast
@@ -24,6 +24,29 @@ Let Variable [ Name=$test ]
     ]
     LiteralExpr [FALSE]
     LiteralExpr [TRUE]
+    LiteralExpr [STRING] [160.25]
+    LiteralExpr [STRING] [160.5]
+    LiteralExpr [STRING] [160.75]
+    LiteralExpr [STRING] [-160.25]
+    LiteralExpr [STRING] [-160.5]
+    LiteralExpr [STRING] [-160.75]
+    LiteralExpr [STRING] [16.125e1]
+    LiteralExpr [STRING] [-1612.5e-1]
+    FunctionCall asterix.int32@1[
+      LiteralExpr [LONG] [99999]
+    ]
+    FunctionCall asterix.int64@1[
+      LiteralExpr [LONG] [99999]
+    ]
+    FunctionCall asterix.float@1[
+      LiteralExpr [LONG] [99999]
+    ]
+    FunctionCall asterix.double@1[
+      LiteralExpr [LONG] [99999]
+    ]
+    LiteralExpr [STRING] [INF]
+    LiteralExpr [STRING] [-INF]
+    LiteralExpr [STRING] [NaN]
   ]
 Let Variable [ Name=$testNull ]
   :=
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.5.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.5.ast
index f3fa67c..5190253 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.5.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.5.ast
@@ -24,6 +24,26 @@ Let Variable [ Name=$test ]
     ]
     LiteralExpr [FALSE]
     LiteralExpr [TRUE]
+    LiteralExpr [STRING] [320.25]
+    LiteralExpr [STRING] [320.5]
+    LiteralExpr [STRING] [320.75]
+    LiteralExpr [STRING] [-320.25]
+    LiteralExpr [STRING] [-320.5]
+    LiteralExpr [STRING] [-320.75]
+    LiteralExpr [STRING] [32.125e1]
+    LiteralExpr [STRING] [-3212.5e-1]
+    FunctionCall asterix.int64@1[
+      LiteralExpr [LONG] [9999999999]
+    ]
+    FunctionCall asterix.float@1[
+      LiteralExpr [LONG] [9999999999]
+    ]
+    FunctionCall asterix.double@1[
+      LiteralExpr [LONG] [9999999999]
+    ]
+    LiteralExpr [STRING] [INF]
+    LiteralExpr [STRING] [-INF]
+    LiteralExpr [STRING] [NaN]
   ]
 Let Variable [ Name=$testNull ]
   :=
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.6.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.6.ast
index 2c793b6..eba1e91 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.6.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/constructor/int_01/int_01.6.ast
@@ -25,6 +25,23 @@ Let Variable [ Name=$test ]
     ]
     LiteralExpr [FALSE]
     LiteralExpr [TRUE]
+    LiteralExpr [STRING] [640.25]
+    LiteralExpr [STRING] [640.5]
+    LiteralExpr [STRING] [640.75]
+    LiteralExpr [STRING] [-640.25]
+    LiteralExpr [STRING] [-640.5]
+    LiteralExpr [STRING] [-640.75]
+    LiteralExpr [STRING] [64.125e1]
+    LiteralExpr [STRING] [-6412.5e-1]
+    FunctionCall asterix.float@1[
+      LiteralExpr [STRING] [1e100]
+    ]
+    FunctionCall asterix.double@1[
+      LiteralExpr [STRING] [1e100]
+    ]
+    LiteralExpr [STRING] [INF]
+    LiteralExpr [STRING] [-INF]
+    LiteralExpr [STRING] [NaN]
   ]
 Let Variable [ Name=$testNull ]
   :=
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/AbstractDataParser.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/AbstractDataParser.java
index 6c84403..400ddf8 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/AbstractDataParser.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/AbstractDataParser.java
@@ -408,7 +408,7 @@ public abstract class AbstractDataParser implements IDataParser {
     }
 
     protected void parseInt64(char[] buffer, int begin, int len, AMutableInt64 result) throws ParseException {
-        if (!NumberUtils.parseInt64(buffer, begin, begin + len, StringUtil.getCharArrayAccessor(), result)) {
+        if (!NumberUtils.parseInt64(buffer, begin, begin + len, StringUtil.getCharArrayAccessor(), result, null)) {
             throw new ParseException(ErrorCode.PARSER_ADM_DATA_PARSER_WRONG_INSTANCE, new String(buffer, begin, len),
                     BuiltinType.AINT64.getTypeName());
         }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/NumberUtils.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/NumberUtils.java
index 19bff61..d4cce79 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/NumberUtils.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/NumberUtils.java
@@ -25,6 +25,7 @@ import org.apache.asterix.om.base.AMutableInt16;
 import org.apache.asterix.om.base.AMutableInt32;
 import org.apache.asterix.om.base.AMutableInt64;
 import org.apache.asterix.om.base.AMutableInt8;
+import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
 import org.apache.hyracks.util.StringUtil;
 
@@ -99,17 +100,22 @@ public final class NumberUtils {
      * Parses string as bigint
      * @param textPtr input string
      * @param result placeholder for the result
+     * @param maybeNumeric if parsing was unsuccessful indicates whether the input string might
+     *                     contain a non-integer numeric value
      * @return {@code true} if parsing was successful, {@code false} otherwise
      */
-    public static boolean parseInt64(UTF8StringPointable textPtr, AMutableInt64 result) {
+    public static boolean parseInt64(UTF8StringPointable textPtr, AMutableInt64 result, MutableBoolean maybeNumeric) {
         byte[] bytes = textPtr.getByteArray();
         int offset = textPtr.getCharStartOffset();
         int end = textPtr.getStartOffset() + textPtr.getLength();
-        return parseInt64(bytes, offset, end, StringUtil.getByteArrayAsCharAccessor(), result);
+        return parseInt64(bytes, offset, end, StringUtil.getByteArrayAsCharAccessor(), result, maybeNumeric);
     }
 
     public static <T> boolean parseInt64(T input, int begin, int end, StringUtil.ICharAccessor<T> charAccessor,
-            AMutableInt64 result) {
+            AMutableInt64 result, MutableBoolean maybeNumeric) {
+        if (maybeNumeric != null) {
+            maybeNumeric.setFalse();
+        }
         int offset = begin;
         //accumulating value in negative domain
         //otherwise Long.MIN_VALUE = -(Long.MAX_VALUE + 1) would have caused overflow
@@ -134,6 +140,9 @@ public final class NumberUtils {
                     && charAccessor.charAt(input, offset + 2) == '4' && offset + 3 == end) {
                 break;
             } else {
+                if (maybeNumeric != null) {
+                    maybeNumeric.setValue(isNumericNonDigitOrSignChar(c));
+                }
                 return false;
             }
             if (value < limit + digit) {
@@ -155,9 +164,14 @@ public final class NumberUtils {
      * Parses string as integer
      * @param textPtr input string
      * @param result placeholder for the result
+     * @param maybeNumeric if parsing was unsuccessful indicates whether the input string might
+     *                     contain a non-integer numeric value
      * @return {@code true} if parsing was successful, {@code false} otherwise
      */
-    public static boolean parseInt32(UTF8StringPointable textPtr, AMutableInt32 result) {
+    public static boolean parseInt32(UTF8StringPointable textPtr, AMutableInt32 result, MutableBoolean maybeNumeric) {
+        if (maybeNumeric != null) {
+            maybeNumeric.setFalse();
+        }
         byte[] bytes = textPtr.getByteArray();
         int offset = textPtr.getCharStartOffset();
         //accumulating value in negative domain
@@ -182,6 +196,9 @@ public final class NumberUtils {
                     && offset + 3 == end) {
                 break;
             } else {
+                if (maybeNumeric != null) {
+                    maybeNumeric.setValue(isNumericNonDigitOrSignChar(bytes[offset]));
+                }
                 return false;
             }
             if (value < limit + digit) {
@@ -203,9 +220,14 @@ public final class NumberUtils {
      * Parses string as smallint
      * @param textPtr input string
      * @param result placeholder for the result
+     * @param maybeNumeric if parsing was unsuccessful indicates whether the input string might
+     *                     contain a non-integer numeric value
      * @return {@code true} if parsing was successful, {@code false} otherwise
      */
-    public static boolean parseInt16(UTF8StringPointable textPtr, AMutableInt16 result) {
+    public static boolean parseInt16(UTF8StringPointable textPtr, AMutableInt16 result, MutableBoolean maybeNumeric) {
+        if (maybeNumeric != null) {
+            maybeNumeric.setFalse();
+        }
         byte[] bytes = textPtr.getByteArray();
         int offset = textPtr.getCharStartOffset();
         //accumulating value in negative domain
@@ -230,6 +252,9 @@ public final class NumberUtils {
                     && offset + 3 == end) {
                 break;
             } else {
+                if (maybeNumeric != null) {
+                    maybeNumeric.setValue(isNumericNonDigitOrSignChar(bytes[offset]));
+                }
                 return false;
             }
             if (value < limit + digit) {
@@ -251,9 +276,14 @@ public final class NumberUtils {
      * Parses string as tinyint
      * @param textPtr input string
      * @param result placeholder for the result
+     * @param maybeNumeric if parsing was unsuccessful indicates whether the input string might
+     *                     contain a non-integer numeric value
      * @return {@code true} if parsing was successful, {@code false} otherwise
      */
-    public static boolean parseInt8(UTF8StringPointable textPtr, AMutableInt8 result) {
+    public static boolean parseInt8(UTF8StringPointable textPtr, AMutableInt8 result, MutableBoolean maybeNumeric) {
+        if (maybeNumeric != null) {
+            maybeNumeric.setFalse();
+        }
         byte[] bytes = textPtr.getByteArray();
         int offset = textPtr.getCharStartOffset();
         //accumulating value in negative domain
@@ -277,6 +307,9 @@ public final class NumberUtils {
             } else if (bytes[offset] == 'i' && bytes[offset + 1] == '8' && offset + 2 == end) {
                 break;
             } else {
+                if (maybeNumeric != null) {
+                    maybeNumeric.setValue(isNumericNonDigitOrSignChar(bytes[offset]));
+                }
                 return false;
             }
             if (value < limit + digit) {
@@ -341,4 +374,21 @@ public final class NumberUtils {
             return false;
         }
     }
+
+    private static boolean isNumericNonDigitOrSignChar(char v) {
+        switch (v) {
+            case '.':
+            case 'E':
+            case 'e':
+            case 'I': // INF
+            case 'N': // NaN
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private static boolean isNumericNonDigitOrSignChar(byte v) {
+        return isNumericNonDigitOrSignChar((char) v);
+    }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt16ConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt16ConstructorEvaluator.java
index 5e2755b..ac75877 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt16ConstructorEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt16ConstructorEvaluator.java
@@ -19,17 +19,17 @@
 
 package org.apache.asterix.runtime.evaluators.constructors;
 
-import java.io.IOException;
-
 import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AFloat;
 import org.apache.asterix.om.base.AInt16;
+import org.apache.asterix.om.base.AMutableFloat;
 import org.apache.asterix.om.base.AMutableInt16;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.runtime.evaluators.common.NumberUtils;
+import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -38,14 +38,22 @@ import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
 
-public abstract class AbstractInt16ConstructorEvaluator extends AbstractConstructorEvaluator {
+public abstract class AbstractInt16ConstructorEvaluator extends AbstractIntConstructorEvaluator {
 
     private final AMutableInt16 aInt16 = new AMutableInt16((short) 0);
     @SuppressWarnings("unchecked")
     private final ISerializerDeserializer<AInt16> int16Serde =
             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT16);
+
+    private final AMutableFloat aFloat = new AMutableFloat(0);
+    @SuppressWarnings("unchecked")
+    private final ISerializerDeserializer<AFloat> floatSerdeNonTagged =
+            SerializerDeserializerProvider.INSTANCE.getNonTaggedSerializerDeserializer(BuiltinType.AFLOAT);
+
     private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
 
+    private final MutableBoolean maybeNumeric = new MutableBoolean();
+
     protected AbstractInt16ConstructorEvaluator(IEvaluatorContext ctx, IScalarEvaluator inputEval,
             SourceLocation sourceLoc) {
         super(ctx, inputEval, sourceLoc);
@@ -62,27 +70,13 @@ public abstract class AbstractInt16ConstructorEvaluator extends AbstractConstruc
                 result.set(inputArg);
                 break;
             case TINYINT:
-                resultStorage.reset();
-                try {
-                    ATypeHierarchy.getTypePromoteComputer(inputType, ATypeTag.SMALLINT).convertType(bytes,
-                            startOffset + 1, len - 1, out);
-                } catch (IOException e) {
-                    throw HyracksDataException.create(e);
-                }
-                result.set(resultStorage);
+                promoteNumeric(inputType, bytes, startOffset + 1, len - 1, result);
                 break;
             case INTEGER:
             case BIGINT:
             case FLOAT:
             case DOUBLE:
-                resultStorage.reset();
-                try {
-                    ATypeHierarchy.getTypeDemoteComputer(inputType, ATypeTag.SMALLINT, false).convertType(bytes,
-                            startOffset + 1, len - 1, out);
-                } catch (IOException e) {
-                    throw HyracksDataException.create(e);
-                }
-                result.set(resultStorage);
+                demoteNumeric(inputType, bytes, startOffset + 1, len - 1, result);
                 break;
             case BOOLEAN:
                 boolean b = ABooleanSerializerDeserializer.getBoolean(bytes, startOffset + 1);
@@ -93,10 +87,15 @@ public abstract class AbstractInt16ConstructorEvaluator extends AbstractConstruc
                 break;
             case STRING:
                 utf8Ptr.set(bytes, startOffset + 1, len - 1);
-                if (NumberUtils.parseInt16(utf8Ptr, aInt16)) {
+                if (NumberUtils.parseInt16(utf8Ptr, aInt16, maybeNumeric)) {
                     resultStorage.reset();
                     int16Serde.serialize(aInt16, out);
                     result.set(resultStorage);
+                } else if (maybeNumeric.booleanValue() && NumberUtils.parseFloat(utf8Ptr, aFloat)) {
+                    tmpStorage.reset();
+                    floatSerdeNonTagged.serialize(aFloat, tmpOut);
+                    demoteNumeric(ATypeTag.FLOAT, tmpStorage.getByteArray(), tmpStorage.getStartOffset(),
+                            tmpStorage.getLength(), result);
                 } else {
                     handleParseError(utf8Ptr, result);
                 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt32ConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt32ConstructorEvaluator.java
index 7d36307..7b2e198 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt32ConstructorEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt32ConstructorEvaluator.java
@@ -19,17 +19,17 @@
 
 package org.apache.asterix.runtime.evaluators.constructors;
 
-import java.io.IOException;
-
 import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.ADouble;
 import org.apache.asterix.om.base.AInt32;
+import org.apache.asterix.om.base.AMutableDouble;
 import org.apache.asterix.om.base.AMutableInt32;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.runtime.evaluators.common.NumberUtils;
+import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -38,14 +38,22 @@ import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
 
-public abstract class AbstractInt32ConstructorEvaluator extends AbstractConstructorEvaluator {
+public abstract class AbstractInt32ConstructorEvaluator extends AbstractIntConstructorEvaluator {
 
     private final AMutableInt32 aInt32 = new AMutableInt32(0);
     @SuppressWarnings("unchecked")
     private final ISerializerDeserializer<AInt32> int32Serde =
             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT32);
+
+    private final AMutableDouble aDouble = new AMutableDouble(0);
+    @SuppressWarnings("unchecked")
+    private final ISerializerDeserializer<ADouble> doubleSerdeNonTagged =
+            SerializerDeserializerProvider.INSTANCE.getNonTaggedSerializerDeserializer(BuiltinType.ADOUBLE);
+
     private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
 
+    private final MutableBoolean maybeNumeric = new MutableBoolean();
+
     protected AbstractInt32ConstructorEvaluator(IEvaluatorContext ctx, IScalarEvaluator inputEval,
             SourceLocation sourceLoc) {
         super(ctx, inputEval, sourceLoc);
@@ -63,26 +71,12 @@ public abstract class AbstractInt32ConstructorEvaluator extends AbstractConstruc
                 break;
             case TINYINT:
             case SMALLINT:
-                resultStorage.reset();
-                try {
-                    ATypeHierarchy.getTypePromoteComputer(inputType, ATypeTag.INTEGER).convertType(bytes,
-                            startOffset + 1, len - 1, out);
-                } catch (IOException e) {
-                    throw HyracksDataException.create(e);
-                }
-                result.set(resultStorage);
+                promoteNumeric(inputType, bytes, startOffset + 1, len - 1, result);
                 break;
             case BIGINT:
             case FLOAT:
             case DOUBLE:
-                resultStorage.reset();
-                try {
-                    ATypeHierarchy.getTypeDemoteComputer(inputType, ATypeTag.INTEGER, false).convertType(bytes,
-                            startOffset + 1, len - 1, out);
-                } catch (IOException e) {
-                    throw HyracksDataException.create(e);
-                }
-                result.set(resultStorage);
+                demoteNumeric(inputType, bytes, startOffset + 1, len - 1, result);
                 break;
             case BOOLEAN:
                 boolean b = ABooleanSerializerDeserializer.getBoolean(bytes, startOffset + 1);
@@ -93,10 +87,15 @@ public abstract class AbstractInt32ConstructorEvaluator extends AbstractConstruc
                 break;
             case STRING:
                 utf8Ptr.set(bytes, startOffset + 1, len - 1);
-                if (NumberUtils.parseInt32(utf8Ptr, aInt32)) {
+                if (NumberUtils.parseInt32(utf8Ptr, aInt32, maybeNumeric)) {
                     resultStorage.reset();
                     int32Serde.serialize(aInt32, out);
                     result.set(resultStorage);
+                } else if (maybeNumeric.booleanValue() && NumberUtils.parseDouble(utf8Ptr, aDouble)) {
+                    tmpStorage.reset();
+                    doubleSerdeNonTagged.serialize(aDouble, tmpOut);
+                    demoteNumeric(ATypeTag.DOUBLE, tmpStorage.getByteArray(), tmpStorage.getStartOffset(),
+                            tmpStorage.getLength(), result);
                 } else {
                     handleParseError(utf8Ptr, result);
                 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt64ConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt64ConstructorEvaluator.java
index b751cae..d02f304 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt64ConstructorEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt64ConstructorEvaluator.java
@@ -19,17 +19,17 @@
 
 package org.apache.asterix.runtime.evaluators.constructors;
 
-import java.io.IOException;
-
 import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.ADouble;
 import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.AMutableDouble;
 import org.apache.asterix.om.base.AMutableInt64;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.runtime.evaluators.common.NumberUtils;
+import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -38,14 +38,22 @@ import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
 
-public abstract class AbstractInt64ConstructorEvaluator extends AbstractConstructorEvaluator {
+public abstract class AbstractInt64ConstructorEvaluator extends AbstractIntConstructorEvaluator {
 
     protected final AMutableInt64 aInt64 = new AMutableInt64(0);
     @SuppressWarnings("unchecked")
     protected final ISerializerDeserializer<AInt64> int64Serde =
             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+
+    private final AMutableDouble aDouble = new AMutableDouble(0);
+    @SuppressWarnings("unchecked")
+    private final ISerializerDeserializer<ADouble> doubleSerdeNonTagged =
+            SerializerDeserializerProvider.INSTANCE.getNonTaggedSerializerDeserializer(BuiltinType.ADOUBLE);
+
     protected final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
 
+    private final MutableBoolean maybeNumeric = new MutableBoolean();
+
     protected AbstractInt64ConstructorEvaluator(IEvaluatorContext ctx, IScalarEvaluator inputEval,
             SourceLocation sourceLoc) {
         super(ctx, inputEval, sourceLoc);
@@ -64,25 +72,11 @@ public abstract class AbstractInt64ConstructorEvaluator extends AbstractConstruc
             case TINYINT:
             case SMALLINT:
             case INTEGER:
-                resultStorage.reset();
-                try {
-                    ATypeHierarchy.getTypePromoteComputer(inputType, ATypeTag.BIGINT).convertType(bytes,
-                            startOffset + 1, len - 1, out);
-                } catch (IOException e) {
-                    throw HyracksDataException.create(e);
-                }
-                result.set(resultStorage);
+                promoteNumeric(inputType, bytes, startOffset + 1, len - 1, result);
                 break;
             case FLOAT:
             case DOUBLE:
-                resultStorage.reset();
-                try {
-                    ATypeHierarchy.getTypeDemoteComputer(inputType, ATypeTag.BIGINT, false).convertType(bytes,
-                            startOffset + 1, len - 1, out);
-                } catch (IOException e) {
-                    throw HyracksDataException.create(e);
-                }
-                result.set(resultStorage);
+                demoteNumeric(inputType, bytes, startOffset + 1, len - 1, result);
                 break;
             case BOOLEAN:
                 resultStorage.reset();
@@ -93,10 +87,15 @@ public abstract class AbstractInt64ConstructorEvaluator extends AbstractConstruc
                 break;
             case STRING:
                 utf8Ptr.set(bytes, startOffset + 1, len - 1);
-                if (NumberUtils.parseInt64(utf8Ptr, aInt64)) {
+                if (NumberUtils.parseInt64(utf8Ptr, aInt64, maybeNumeric)) {
                     resultStorage.reset();
                     int64Serde.serialize(aInt64, out);
                     result.set(resultStorage);
+                } else if (maybeNumeric.booleanValue() && NumberUtils.parseDouble(utf8Ptr, aDouble)) {
+                    tmpStorage.reset();
+                    doubleSerdeNonTagged.serialize(aDouble, tmpOut);
+                    demoteNumeric(ATypeTag.DOUBLE, tmpStorage.getByteArray(), tmpStorage.getStartOffset(),
+                            tmpStorage.getLength(), result);
                 } else {
                     handleParseError(utf8Ptr, result);
                 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt8ConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt8ConstructorEvaluator.java
index d236076..e8c73f5 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt8ConstructorEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt8ConstructorEvaluator.java
@@ -19,17 +19,17 @@
 
 package org.apache.asterix.runtime.evaluators.constructors;
 
-import java.io.IOException;
-
 import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AFloat;
 import org.apache.asterix.om.base.AInt8;
+import org.apache.asterix.om.base.AMutableFloat;
 import org.apache.asterix.om.base.AMutableInt8;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.runtime.evaluators.common.NumberUtils;
+import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -38,14 +38,22 @@ import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
 
-public abstract class AbstractInt8ConstructorEvaluator extends AbstractConstructorEvaluator {
+public abstract class AbstractInt8ConstructorEvaluator extends AbstractIntConstructorEvaluator {
 
     private final AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
     @SuppressWarnings("unchecked")
     private final ISerializerDeserializer<AInt8> int8Serde =
             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT8);
+
+    private final AMutableFloat aFloat = new AMutableFloat(0);
+    @SuppressWarnings("unchecked")
+    private final ISerializerDeserializer<AFloat> floatSerdeNonTagged =
+            SerializerDeserializerProvider.INSTANCE.getNonTaggedSerializerDeserializer(BuiltinType.AFLOAT);
+
     private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
 
+    private final MutableBoolean maybeNumeric = new MutableBoolean();
+
     protected AbstractInt8ConstructorEvaluator(IEvaluatorContext ctx, IScalarEvaluator inputEval,
             SourceLocation sourceLoc) {
         super(ctx, inputEval, sourceLoc);
@@ -66,14 +74,7 @@ public abstract class AbstractInt8ConstructorEvaluator extends AbstractConstruct
             case BIGINT:
             case FLOAT:
             case DOUBLE:
-                resultStorage.reset();
-                try {
-                    ATypeHierarchy.getTypeDemoteComputer(inputType, ATypeTag.TINYINT, false).convertType(bytes,
-                            startOffset + 1, len - 1, out);
-                } catch (IOException e) {
-                    throw HyracksDataException.create(e);
-                }
-                result.set(resultStorage);
+                demoteNumeric(inputType, bytes, startOffset + 1, len - 1, result);
                 break;
             case BOOLEAN:
                 boolean b = ABooleanSerializerDeserializer.getBoolean(bytes, startOffset + 1);
@@ -84,10 +85,16 @@ public abstract class AbstractInt8ConstructorEvaluator extends AbstractConstruct
                 break;
             case STRING:
                 utf8Ptr.set(bytes, startOffset + 1, len - 1);
-                if (NumberUtils.parseInt8(utf8Ptr, aInt8)) {
+                if (NumberUtils.parseInt8(utf8Ptr, aInt8, maybeNumeric)) {
                     resultStorage.reset();
                     int8Serde.serialize(aInt8, out);
                     result.set(resultStorage);
+                } else if (maybeNumeric.booleanValue() && NumberUtils.parseFloat(utf8Ptr, aFloat)) {
+                    tmpStorage.reset();
+                    floatSerdeNonTagged.serialize(aFloat, tmpOut);
+                    demoteNumeric(ATypeTag.FLOAT, tmpStorage.getByteArray(), tmpStorage.getStartOffset(),
+                            tmpStorage.getLength(), result);
+                    break;
                 } else {
                     handleParseError(utf8Ptr, result);
                 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractIntConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractIntConstructorEvaluator.java
new file mode 100644
index 0000000..484fae2
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractIntConstructorEvaluator.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+
+public abstract class AbstractIntConstructorEvaluator extends AbstractConstructorEvaluator {
+
+    protected final ArrayBackedValueStorage tmpStorage;
+    protected final DataOutput tmpOut;
+
+    public AbstractIntConstructorEvaluator(IEvaluatorContext ctx, IScalarEvaluator inputEval,
+            SourceLocation sourceLoc) {
+        super(ctx, inputEval, sourceLoc);
+        tmpStorage = new ArrayBackedValueStorage();
+        tmpOut = tmpStorage.getDataOutput();
+    }
+
+    protected void promoteNumeric(ATypeTag inputType, byte[] bytes, int startOffset, int len, IPointable result)
+            throws HyracksDataException {
+        resultStorage.reset();
+        try {
+            ATypeHierarchy.getTypePromoteComputer(inputType, getTargetType().getTypeTag()).convertType(bytes,
+                    startOffset, len, out);
+            result.set(resultStorage);
+        } catch (IOException e) {
+            throw HyracksDataException.create(e);
+        }
+    }
+
+    protected void demoteNumeric(ATypeTag inputType, byte[] bytes, int startOffset, int len, IPointable result)
+            throws HyracksDataException {
+        resultStorage.reset();
+        try {
+            ATypeHierarchy.getTypeDemoteComputer(inputType, getTargetType().getTypeTag(), false).convertType(bytes,
+                    startOffset, len, out);
+            result.set(resultStorage);
+        } catch (IOException e) {
+            throw HyracksDataException.create(e);
+        }
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToNumberDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToNumberDescriptor.java
index 7017380..5a16efc 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToNumberDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToNumberDescriptor.java
@@ -35,6 +35,7 @@ import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import org.apache.asterix.runtime.evaluators.common.NumberUtils;
 import org.apache.asterix.runtime.exceptions.TypeMismatchException;
+import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
@@ -67,6 +68,7 @@ public class ToNumberDescriptor extends AbstractScalarFunctionDynamicDescriptor
                 final AMutableInt64 aInt64 = new AMutableInt64(0);
                 final AMutableDouble aDouble = new AMutableDouble(0);
                 final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
+                final MutableBoolean maybeNumeric = new MutableBoolean();
 
                 @SuppressWarnings("unchecked")
                 final ISerializerDeserializer<AInt64> INT64_SERDE =
@@ -108,10 +110,10 @@ public class ToNumberDescriptor extends AbstractScalarFunctionDynamicDescriptor
 
                             case STRING:
                                 utf8Ptr.set(bytes, startOffset + 1, inputArg.getLength() - 1);
-                                if (NumberUtils.parseInt64(utf8Ptr, aInt64)) {
+                                if (NumberUtils.parseInt64(utf8Ptr, aInt64, maybeNumeric)) {
                                     INT64_SERDE.serialize(aInt64, out);
                                     result.set(resultStorage);
-                                } else if (NumberUtils.parseDouble(utf8Ptr, aDouble)) {
+                                } else if (maybeNumeric.booleanValue() && NumberUtils.parseDouble(utf8Ptr, aDouble)) {
                                     DOUBLE_SERDE.serialize(aDouble, out);
                                     result.set(resultStorage);
                                 } else {