Repository: shinichi-takii/ddlparse

Issue:
Oracle `NUMBER(*,0)` format causes column parsing to stop
Very excited to find this -- just what I need, so thank you very much for creating it! I created a test to directly call Oracle 12.2.0.1 and run dbms_metadata.get_ddl, which is the standard method for producing DDL from the Oracle database using the CLI. It produces `CREATE TABLE` statements like this, which I then ran through ddlparse to convert to BigQuery -- but I found that most of the columns were missing in the resulting sql. Here's a simple runnable example where I removed the `(*,0)` from the first `NUMBER` column (`COL2_WORKS`):
```python
from ddlparse.ddlparse import DdlParse


def main():

    oracle_ct = """
  CREATE TABLE "MYSCHEMA"."MYTABLE"
   (	"COL1" VARCHAR2(30) NOT NULL ENABLE,
	"COL2_WORKS" NUMBER NOT NULL ENABLE,
	"COL3" VARCHAR2(30) NOT NULL ENABLE,
	"COL4_BROKEN_AFTER_THIS" NUMBER(*,0) NOT NULL ENABLE,
	"COL5" VARCHAR2(8) NOT NULL ENABLE,
	"COL6" VARCHAR2(3) NOT NULL ENABLE
   ) ;
"""

    table = DdlParse().parse(ddl=oracle_ct, source_database=DdlParse.DATABASE.oracle)
    print(table.to_bigquery_ddl())


if __name__ == "__main__":
    main()
```

Note the `NUMBER(*,0` designation.  I found in testing in on many tables that as soon as ddlparse hits any `NUMBER(*,0)` data type column, it stops processing any more columns, so I get BigQuery DDL like this:

```sql
#standardSQL
CREATE TABLE `project.MYSCHEMA.MYTABLE`
(
  COL1 STRING NOT NULL,
  COL2_WORKS FLOAT64 NOT NULL,
  COL3 STRING NOT NULL,
  COL4_BROKEN_AFTER_THIS FLOAT64
)
```

I stepped through the code/breakpoints enough to understand that the issue is happening in the original column parsing, not in the conversion to BQ DDL. The BQ conversion is only called for the 4 columns.

I suspect the `*` is breaking a regex in ddlparse or pyparse. I'm out of time to figure out where, and I'd imagine you will be a lot faster at it since you are familiar with how you're using them, but I wanted to share this much since I got this far.  For now, easily fixed by just preprocessing my Oracle `CREATE TABLE` strings to remove anything with the `*`.

Additional note: it is turning `NUMBER(*,0)` into a FLOAT64 when `NUMBER(*,0)` is an integer - but perhaps that's because of the broken regex as well / it's being cut off.  

Thanks again for the code!

Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aca4078..c9c4098 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,10 +5,30 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 
+## [1.4.0] - 2019-12-08
+### Added
+- Add supports to BigQuery `NUMERIC` data type.
+
+#### Data-type Conditions
+
+|BigQuery Data Type|Source Data Type|Precision|Scale|Database|Exapmle Source Data Type|
+|:--|:--|:-:|:-:|:--|:--|
+|**INT64**|(NUMERIC\|NUMBER\|DECIMAL)|< 19|= 0|-|NUMERIC(18)|
+|**FLOAT64**|(NUMERIC\|NUMBER\|DECIMAL)|< 19|> 0|-|NUMERIC(18, 1)|
+|**NUMERIC**|(NUMERIC\|NUMBER\|DECIMAL)|>= 19|-|-|NUMERIC(19)|
+|**NUMERIC**|(NUMERIC\|NUMBER\|DECIMAL)|\*|-|-|NUMBER(\*, 0)|
+|**INT64**|(NUMERIC\|NUMBER\|DECIMAL)|None|-|default|DECIMAL|
+|**NUMERIC**|(NUMERIC\|NUMBER\|DECIMAL)|None|-|`DdlParse.DATABASE.oracle`<br>`DdlParse.DATABASE.postgresql`|NUMBER<br>NUMERIC|
+
+### Fixed
+- Fix parsing failure for include `(*)` format of Oracle `NUMBER` data type.
+
+
 ## [1.3.1] - 2019-12-05
 ### Fixed
 - Fixed parsing failure for columns include dot at default values.
 
+
 ## [1.3.0] - 2019-06-15
 ### Added
 - Add supports the parse of `COMMENT` statements.
@@ -16,11 +36,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Add `DdlParseColumn.description` property for the `DdlParseColumn.comment` property alias.
 - Add supports column comments in BigQuery DDL.
 
+
 ## [1.2.3] - 2019-02-17
 ### Fixed
 - Fix parse error for MySQL DDL with 'FOREIGN KEY'.
 - Fix not completely parsed with block comments.
 
+
 ## [1.2.2] - 2019-02-02
 ### Added
 - Add supports PostgreSQL data type.
@@ -31,6 +53,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Fix parse `DEFAULT` value.
     - Add parse regex of `DEFAULT` value.
 
+
 ## [1.2.1] - 2019-01-27
 ### Added
 - Add supports for Python 3.7.
@@ -39,9 +62,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
     - `CHARACTER VARYING`
     - `JSON`
     - Array type
+
+### Fixed
 - Fix parse `DEFAULT` value.
     - Add decimal point to `DEFAULT` parse character.
 
+
 ## [1.2.0] - 2019-01-02
 ### Added
 - Add `DdlParseTable.to_bigquery_ddl` function.
@@ -52,12 +78,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Add `DdlParseColumn.bigquery_standard_data_type` property.
     - Get BigQuery Standard SQL data property.
 
+
 ## [1.1.3] - 2018-08-02
 ### Added
 - Add support inline comment.
 - Add support constraint name with quotes.
 - Add support Oracle Length Semantics for Character Datatypes.
 
+
 ## [1.1.2] - 2018-03-25
 ### Added
 - Add support Oracle data type.
@@ -67,10 +95,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Fixed
 - Miner fix.
 
+
 ## [1.1.1] - 2018-03-25
 ### Fixed
 - Fix Postgres/Redshift parse of "::" syntax in field attribute.
 
+
 ## [1.1.0] - 2018-01-14
 ### Added
 - Add `source_database` option.
@@ -81,6 +111,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
     - Oracle 'DATE' -> BigQuery 'DATETIME'
     - Oracle 'NUMBER' -> BigQuery 'INTEGER' or 'FLOAT'
 
+
 ## [1.0.2] - 2018-01-09
 ### Fixed
 - Miner enhancement.
@@ -88,14 +119,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
     - `example.py` : Modified comment.
     - `README.md` : Miner fix.
 
+
 ## [1.0.1] - 2018-01-07
 ### Fixed
 - Miner enhancement.
 
+
 ## [1.0.0]
 ### Added
 - Initial released.
 
+
+[1.4.0]: https://github.com/shinichi-takii/ddlparse/compare/v1.3.1...v1.4.0
 [1.3.1]: https://github.com/shinichi-takii/ddlparse/compare/v1.3.0...v1.3.1
 [1.3.0]: https://github.com/shinichi-takii/ddlparse/compare/v1.2.3...v1.3.0
 [1.2.3]: https://github.com/shinichi-takii/ddlparse/compare/v1.2.2...v1.2.3
diff --git a/ddlparse/__init__.py b/ddlparse/__init__.py
index e7f3440..89272aa 100644
--- a/ddlparse/__init__.py
+++ b/ddlparse/__init__.py
@@ -8,7 +8,7 @@
 from .ddlparse import *
 
 __copyright__    = 'Copyright (C) 2018-2019 Shinichi Takii'
-__version__      = '1.3.1'
+__version__      = '1.4.0'
 __license__      = 'BSD-3-Clause'
 __author__       = 'Shinichi Takii'
 __author_email__ = 'shinichi.takii@gmail.com'
diff --git a/ddlparse/ddlparse.py b/ddlparse/ddlparse.py
index 44b133c..24a7659 100644
--- a/ddlparse/ddlparse.py
+++ b/ddlparse/ddlparse.py
@@ -112,12 +112,12 @@ class DdlParseColumn(DdlParseTableColumnBase):
         if len(data_type_array) < 2:
             return
 
-        matches = re.findall(r"(\d+)\s*,*\s*(\d*)", data_type_array[-1])
+        matches = re.findall(r"([\d\*]+)\s*,*\s*(\d*)", data_type_array[-1])
         if len(matches) > 0:
-            self._length = int(matches[0][0])
+            self._length = matches[0][0] if matches[0][0] == "*" else int(matches[0][0])
             self._scale = None if len(matches[0]) < 2 or matches[0][1] == "" or int(matches[0][1]) == 0 else int(matches[0][1])
 
-        if re.search(r"^\D+", data_type_array[1]):
+        if re.search(r"^[^\d\*]+", data_type_array[1]):
             self._data_type += " {}".format(data_type_array[1])
 
 
@@ -225,15 +225,22 @@ class DdlParseColumn(DdlParseTableColumnBase):
                         return bq_type
 
         if self._data_type in ["NUMERIC", "NUMBER", "DECIMAL"]:
-            if self._scale is not None:
-                return "FLOAT"
+            if self._length is None:
+                if self._source_database in [self.DATABASE.oracle, self.DATABASE.postgresql]:
+                    return "NUMERIC"
+                else:
+                    return "INTEGER"
 
-            if self._data_type == "NUMBER" \
-                and self._source_database == self.DATABASE.oracle \
-                and self._length is None:
-                return "FLOAT"
+            if self._length == "*":
+                return "NUMERIC"
 
-            return "INTEGER"
+            if self._length < 19:
+                if self._scale is None or self._scale == 0:
+                    return "INTEGER"
+                else:
+                    return "FLOAT"
+
+            return "NUMERIC"
 
         raise ValueError("Unknown data type : '{}'".format(self._data_type))
 
@@ -521,7 +528,7 @@ class DdlParse(DdlParseBase):
                     + Group(
                           Word(alphanums+"_")
                         + Optional(CaselessKeyword("WITHOUT TIME ZONE") ^ CaselessKeyword("WITH TIME ZONE") ^ CaselessKeyword("PRECISION") ^ CaselessKeyword("VARYING"))
-                        + Optional(_LPAR + Regex(r"\d+\s*,*\s*\d*") + Optional(Suppress(_CHAR_SEMANTICS | _BYTE_SEMANTICS)) + _RPAR)
+                        + Optional(_LPAR + Regex(r"[\d\*]+\s*,*\s*\d*") + Optional(Suppress(_CHAR_SEMANTICS | _BYTE_SEMANTICS)) + _RPAR)
                         )("type")
                     + Optional(Word(r"\[\]"))("array_brackets")
                     + Optional(Regex(r"(?!--)(\b(COMMENT|DEFAULT)\b\s+[^,]+|([A-Za-z0-9_\.'\": -]|[^\x01-\x7E])*)", re.IGNORECASE))("constraint")


Test patch:
diff --git a/test/test_ddlparse.py b/test/test_ddlparse.py
index 9bf5a76..b8d32de 100644
--- a/test/test_ddlparse.py
+++ b/test/test_ddlparse.py
@@ -34,15 +34,36 @@ TEST_DATA = {
               Col_18 timestamptz,
               Col_19 timestamp with time zone,
               Col_20 bool,
-              Col_21 numeric(10),
-              Col_22 number(10),
-              Col_23 decimal(20),
-              Col_24 numeric(30,0),
-              Col_25 number(30,0),
-              Col_26 decimal(40,0),
-              Col_27 numeric(50,1),
-              Col_28 number(50,1), -- comment
-              Col_29 decimal(60,2)  -- comment
+              Col_21 numeric(18),
+              Col_22 number(18),
+              Col_23 decimal(18),
+              Col_24 numeric(18, 0),
+              Col_25 number(18, 0),
+              Col_26 decimal(18, 0),
+              Col_27 numeric(18, 1),
+              Col_28 number(18, 2),
+              Col_29 decimal(18, 3),
+              Col_30 numeric(19),
+              Col_31 number(19),
+              Col_32 decimal(19),
+              Col_33 numeric(19, 0),
+              Col_34 number(19, 0),
+              Col_35 decimal(19, 0),
+              Col_36 numeric(19, 1),
+              Col_37 number(19, 2),
+              Col_38 decimal(19, 3),
+              Col_39 numeric(*),
+              Col_40 number(*),
+              Col_41 decimal(*),
+              Col_42 numeric(*, 0),
+              Col_43 number(*, 0),
+              Col_44 decimal(*, 0),
+              Col_45 numeric(*, 1), -- comment
+              Col_46 number(*, 2),  -- comment
+              Col_47 decimal(*, 3),  -- comment
+              Col_48 numeric,
+              Col_49 number,
+              Col_50 decimal
             );
             """,
         "database" : None,
@@ -68,15 +89,36 @@ TEST_DATA = {
             {"name" : "Col_18", "type" : "TIMESTAMPTZ", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
             {"name" : "Col_19", "type" : "TIMESTAMP WITH TIME ZONE", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
             {"name" : "Col_20", "type" : "BOOL", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_21", "type" : "NUMERIC", "length" : 10, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_22", "type" : "NUMBER", "length" : 10, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_23", "type" : "DECIMAL", "length" : 20, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_24", "type" : "NUMERIC", "length" : 30, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_25", "type" : "NUMBER", "length" : 30, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_26", "type" : "DECIMAL", "length" : 40, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_27", "type" : "NUMERIC", "length" : 50, "scale" : 1, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_28", "type" : "NUMBER", "length" : 50, "scale" : 1, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
-            {"name" : "Col_29", "type" : "DECIMAL", "length" : 60, "scale" : 2, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_21", "type" : "NUMERIC", "length" : 18, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_22", "type" : "NUMBER", "length" : 18, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_23", "type" : "DECIMAL", "length" : 18, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_24", "type" : "NUMERIC", "length" : 18, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_25", "type" : "NUMBER", "length" : 18, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_26", "type" : "DECIMAL", "length" : 18, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_27", "type" : "NUMERIC", "length" : 18, "scale" : 1, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_28", "type" : "NUMBER", "length" : 18, "scale" : 2, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_29", "type" : "DECIMAL", "length" : 18, "scale" : 3, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_30", "type" : "NUMERIC", "length" : 19, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_31", "type" : "NUMBER", "length" : 19, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_32", "type" : "DECIMAL", "length" : 19, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_33", "type" : "NUMERIC", "length" : 19, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_34", "type" : "NUMBER", "length" : 19, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_35", "type" : "DECIMAL", "length" : 19, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_36", "type" : "NUMERIC", "length" : 19, "scale" : 1, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_37", "type" : "NUMBER", "length" : 19, "scale" : 2, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_38", "type" : "DECIMAL", "length" : 19, "scale" : 3, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_39", "type" : "NUMERIC", "length" : "*", "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_40", "type" : "NUMBER", "length" : "*", "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_41", "type" : "DECIMAL", "length" : "*", "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_42", "type" : "NUMERIC", "length" : "*", "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_43", "type" : "NUMBER", "length" : "*", "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_44", "type" : "DECIMAL", "length" : "*", "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_45", "type" : "NUMERIC", "length" : "*", "scale" : 1, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_46", "type" : "NUMBER", "length" : "*", "scale" : 2, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_47", "type" : "DECIMAL", "length" : "*", "scale" : 3, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_48", "type" : "NUMERIC", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_49", "type" : "NUMBER", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_50", "type" : "DECIMAL", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
         ],
         "bq_field" : [
             '{"name": "Col_01", "type": "STRING", "mode": "REQUIRED"}',
@@ -108,6 +150,27 @@ TEST_DATA = {
             '{"name": "Col_27", "type": "FLOAT", "mode": "NULLABLE"}',
             '{"name": "Col_28", "type": "FLOAT", "mode": "NULLABLE"}',
             '{"name": "Col_29", "type": "FLOAT", "mode": "NULLABLE"}',
+            '{"name": "Col_30", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_31", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_32", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_33", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_34", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_35", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_36", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_37", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_38", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_39", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_40", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_41", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_42", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_43", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_44", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_45", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_46", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_47", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_48", "type": "INTEGER", "mode": "NULLABLE"}',
+            '{"name": "Col_49", "type": "INTEGER", "mode": "NULLABLE"}',
+            '{"name": "Col_50", "type": "INTEGER", "mode": "NULLABLE"}',
         ],
         "bq_standard_data_type" : [
             "STRING",
@@ -139,6 +202,27 @@ TEST_DATA = {
             "FLOAT64",
             "FLOAT64",
             "FLOAT64",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "NUMERIC",
+            "INT64",
+            "INT64",
+            "INT64",
         ],
     },
 
@@ -260,7 +344,7 @@ TEST_DATA = {
             '{"name": "Col_02", "type": "STRING", "mode": "NULLABLE"}',
             '{"name": "Col_03", "type": "INTEGER", "mode": "NULLABLE"}',
             '{"name": "Col_04", "type": "INTEGER", "mode": "NULLABLE"}',
-            '{"name": "Col_05", "type": "FLOAT", "mode": "NULLABLE"}',
+            '{"name": "Col_05", "type": "NUMERIC", "mode": "NULLABLE"}',
             '{"name": "Col_06", "type": "STRING", "mode": "REPEATED"}',
         ],
         "bq_standard_data_type" : [
@@ -268,7 +352,7 @@ TEST_DATA = {
             "STRING",
             "INT64",
             "INT64",
-            "FLOAT64",
+            "NUMERIC",
             "STRING",
         ],
     },
@@ -304,7 +388,7 @@ TEST_DATA = {
             '{"name": "Col_01", "type": "DATETIME", "mode": "NULLABLE"}',
             '{"name": "Col_02", "type": "INTEGER", "mode": "NULLABLE"}',
             '{"name": "Col_03", "type": "FLOAT", "mode": "NULLABLE"}',
-            '{"name": "Col_04", "type": "FLOAT", "mode": "NULLABLE"}',
+            '{"name": "Col_04", "type": "NUMERIC", "mode": "NULLABLE"}',
             '{"name": "Col_05", "type": "STRING", "mode": "NULLABLE"}',
             '{"name": "Col_06", "type": "STRING", "mode": "NULLABLE"}',
             '{"name": "Col_07", "type": "STRING", "mode": "NULLABLE"}',
@@ -314,7 +398,7 @@ TEST_DATA = {
             "DATETIME",
             "INT64",
             "FLOAT64",
-            "FLOAT64",
+            "NUMERIC",
             "STRING",
             "STRING",
             "STRING",
@@ -333,10 +417,12 @@ TEST_DATA = {
               Col_04 integer[][], -- two dimensional array
               Col_05 integer[][][], -- multiple dimensional array
               Col_06 character varying[], -- character varying array
-              Col_07 uuid NOT NULL
+              Col_07 uuid NOT NULL,
+              Col_08 numeric,
+              Col_09 decimal
             );
             """,
-        "database" : None,
+        "database" : DdlParse.DATABASE.postgresql,
         "table" : {"schema" : None, "name" : "Sample_Table", "temp" : False},
         "columns" : [
             {"name" : "Col_01", "type" : "CHARACTER VARYING", "length" : 100, "scale" : None, "array_dimensional" : 0, "not_null" : True, "pk" : True, "unique" : False, "constraint" : "PRIMARY KEY", "description" : None},
@@ -346,6 +432,8 @@ TEST_DATA = {
             {"name" : "Col_05", "type" : "INTEGER", "length" : None, "scale" : None, "array_dimensional" : 3, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
             {"name" : "Col_06", "type" : "CHARACTER VARYING", "length" : None, "scale" : None, "array_dimensional" : 1, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
             {"name" : "Col_07", "type" : "UUID", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : True, "pk" : False, "unique" : False, "constraint" : "NOT NULL", "description" : None},
+            {"name" : "Col_08", "type" : "NUMERIC", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
+            {"name" : "Col_09", "type" : "DECIMAL", "length" : None, "scale" : None, "array_dimensional" : 0, "not_null" : False, "pk" : False, "unique" : False, "constraint" : "", "description" : None},
         ],
         "bq_field" : [
             '{"name": "Col_01", "type": "STRING", "mode": "REQUIRED"}',
@@ -355,6 +443,8 @@ TEST_DATA = {
             '{"name": "Col_05", "type": "RECORD", "mode": "REPEATED", "fields": [{"name": "dimension_1", "type": "RECORD", "mode": "REPEATED", "fields": [{"name": "dimension_2", "type": "INTEGER", "mode": "REPEATED"}]}]}',
             '{"name": "Col_06", "type": "STRING", "mode": "REPEATED"}',
             '{"name": "Col_07", "type": "STRING", "mode": "REQUIRED"}',
+            '{"name": "Col_08", "type": "NUMERIC", "mode": "NULLABLE"}',
+            '{"name": "Col_09", "type": "NUMERIC", "mode": "NULLABLE"}',
         ],
         "bq_standard_data_type" : [
             "STRING",
@@ -364,6 +454,8 @@ TEST_DATA = {
             "INT64",
             "STRING",
             "STRING",
+            "NUMERIC",
+            "NUMERIC",
         ],
     },