)]}'
{"neutron/db/migration/alembic_migrations/env.py":[{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"38fd713350081db219fe557a3d02a00b4406f1c3","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from sqlalchemy import event"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from neutron.db.migration.alembic_migrations import external"},{"line_number":21,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj  # noqa"},{"line_number":22,"context_line":"from neutron.db.migration import autogen"},{"line_number":23,"context_line":"from neutron.db.migration.connection import DBConnection"},{"line_number":24,"context_line":"from neutron.db.migration.models import head  # noqa"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_8b784e2d","line":21,"updated":"2016-05-12 14:23:31.000000000","message":"Why is this needed? (Question is for Mike.)","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"5bb74bf39f068aa0b3596d4ed170cd5802c3fe25","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from sqlalchemy import event"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from neutron.db.migration.alembic_migrations import external"},{"line_number":21,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj  # noqa"},{"line_number":22,"context_line":"from neutron.db.migration import autogen"},{"line_number":23,"context_line":"from neutron.db.migration.connection import DBConnection"},{"line_number":24,"context_line":"from neutron.db.migration.models import head  # noqa"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_675d52ec","line":21,"in_reply_to":"dab17558_615d42ec","updated":"2016-05-12 18:19:45.000000000","message":"touche\u0027, because the migration file itself imports it anyway.  fine we can take it out.","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"e0855027a31c584f20b5a1ab0e964580caa1fa62","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from sqlalchemy import event"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from neutron.db.migration.alembic_migrations import external"},{"line_number":21,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj  # noqa"},{"line_number":22,"context_line":"from neutron.db.migration import autogen"},{"line_number":23,"context_line":"from neutron.db.migration.connection import DBConnection"},{"line_number":24,"context_line":"from neutron.db.migration.models import head  # noqa"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_9334004b","line":21,"in_reply_to":"dab17558_8b784e2d","updated":"2016-05-12 16:58:19.000000000","message":"there are structures in that module that are registered as plugins to alembic.op itself.  this is how the migration is able to call op.create_ap() and op.create_trigger().","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"},{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"32c35be5ba95c9f6ab48cccf8370976abfc6b7e1","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from sqlalchemy import event"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from neutron.db.migration.alembic_migrations import external"},{"line_number":21,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj  # noqa"},{"line_number":22,"context_line":"from neutron.db.migration import autogen"},{"line_number":23,"context_line":"from neutron.db.migration.connection import DBConnection"},{"line_number":24,"context_line":"from neutron.db.migration.models import head  # noqa"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_615d42ec","line":21,"in_reply_to":"dab17558_9334004b","updated":"2016-05-12 17:30:19.000000000","message":"I commented it out and it worked anyway. ?","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"}],"neutron/db/migration/alembic_migrations/replaceable_obj.py":[{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"92d0bc21c39b6ff80bb331abee0ae67fb5bd74cf","unresolved":false,"context_lines":[{"line_number":147,"context_line":"    )"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"def upgrade():"},{"line_number":151,"context_line":"    op.create_sp(add_customer_sp)"},{"line_number":152,"context_line":"    op.create_trigger(add_customer_trigger)"}],"source_content_type":"text/x-python","patch_set":3,"id":"dab17558_3cfc653d","line":150,"range":{"start_line":150,"start_character":11,"end_line":150,"end_character":14},"updated":"2016-05-11 04:57:08.000000000","message":"Dear Mr.Mike\n\nThanks for your time. I aleady updated new patch set that following your suggestion.\n\nFor more detail: In this patch set, I am focussing on step3. For step 4, I am still thinking how to alemic/sqlalchemy can detect backend DB to apply Database-style command. \n\n\nIn this file replaceable_object, If we can detect the type of backend DB then we will write a function to choose command.\n\nFor example: Content as this file:\n\n\"\"\"\nadd_customer_trigger_for_mysql \u003d ReplaceableObject()\nadd_customer_trigger_for_postgresql \u003d ReplaceableObject()\nadd_customer_trigger_for_other_sql \u003d ReplaceableObject()\n\n...\n\ndef upgrade():\n\tif check_backend_DB \u003d\u003d \u0027mysql\u0027\n\t\top.create_sp(add_customer_sp_for_mysql)\n\t    op.create_trigger(add_customer_trigger_for_mysql)\n\tifesle check_backend_DB \u003d\u003d \u0027postgresql\u0027\n\t\top.create_sp(add_customer_sp_for_postgresql)\n\t    op.create_trigger(add_customer_trigger_for_postgresql)\n\n\"\"\"\n\nHow do you think about this idea?","commit_id":"55224318b68270a5475a126c1ec24117a1fa88fb"}],"neutron/db/migration/alembic_migrations/versions/newton/expand/23c280e37c2c_add_sp_and_trigger_for_mysql_and_add_.py":[{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"7b42096c1f8ef3a3ad3e5442e7025ebeeb041484","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    DECLARE bitmask INT;"},{"line_number":37,"context_line":"    SET bitmask \u003d pow("},{"line_number":38,"context_line":"        2,"},{"line_number":39,"context_line":"        (32 - least("},{"line_number":40,"context_line":"            cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":41,"context_line":"            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)"},{"line_number":42,"context_line":"        ))"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_499c49c0","line":39,"updated":"2016-05-25 20:39:58.000000000","message":"How will this work if someone creates an IPv6 subnet?","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"1c11ba25e19c65749f3627a6b8e40d033ead897f","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    DECLARE bitmask INT;"},{"line_number":37,"context_line":"    SET bitmask \u003d pow("},{"line_number":38,"context_line":"        2,"},{"line_number":39,"context_line":"        (32 - least("},{"line_number":40,"context_line":"            cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":41,"context_line":"            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)"},{"line_number":42,"context_line":"        ))"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_b5f702d2","line":39,"in_reply_to":"bab6814e_499c49c0","updated":"2016-05-25 22:56:50.000000000","message":"i believe this function needs to be amended to include two conditional paths, one that works for ipv6.","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":15905,"name":"Cao Xuan Hoang","email":"xuanhoangqb@gmail.com","username":"hoangcx"},"change_message_id":"1cb86544af4dc6320dc5d42ac5eee841090c3ed7","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    DECLARE bitmask INT;"},{"line_number":37,"context_line":"    SET bitmask \u003d pow("},{"line_number":38,"context_line":"        2,"},{"line_number":39,"context_line":"        (32 - least("},{"line_number":40,"context_line":"            cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":41,"context_line":"            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)"},{"line_number":42,"context_line":"        ))"}],"source_content_type":"text/x-python","patch_set":8,"id":"9abb7d3a_0c0e4634","line":39,"in_reply_to":"bab6814e_92ef5f1d","updated":"2016-05-27 10:33:52.000000000","message":"Example for lower version of Mysql-5.5, but it needs to test more:\n\n-- --------------------------------------------------------------------------------\n-- Routine DDL\n-- Note: comments before and after the routine body will not be stored by the server\n-- --------------------------------------------------------------------------------\nDELIMITER $$\n\nCREATE DEFINER\u003d`root`@`localhost` FUNCTION `cidr_overlap`(cidr1 varchar(86), ip_version_1 tinyint, cidr2 varchar(86), ip_version_2 tinyint) RETURNS tinyint(4)\nBEGIN\n    DECLARE ipv61, ipv62 INT;\n    DECLARE bitmask INT DEFAULT 0;\n    DECLARE tmp, a, b TINYINT DEFAULT 0;\n    DECLARE result TINYINT DEFAULT 0;\n    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN\n        SET bitmask \u003d least(cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),\n                            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));\n        SET a \u003d (bitmask DIV 16);\n        SET b \u003d (bitmask % 16);\n        masking : WHILE a \u003e\u003d 0 DO\n            SET ipv61 \u003d CONV(substring_index(substring_index(cidr1, \u0027:\u0027, (8 - tmp)), \u0027:\u0027, -1), 16, 10);\n            SET ipv62 \u003d CONV(substring_index(substring_index(cidr2, \u0027:\u0027, (8 - tmp)), \u0027:\u0027, -1), 16, 10);\n            SET tmp \u003d tmp + 1;\n            IF (a !\u003d 0) THEN\n                IF (ipv61 !\u003d ipv62 !\u003d NULL) THEN\n                    SET result \u003d 1;\n                END IF;\n            ELSE\n                IF (ipv61 \u0026 ~(pow(2,b) - 1)) !\u003d (ipv62 \u0026 ~(pow(2,b) - 1)) THEN\n                    SET result \u003d 1;\n                END IF;\n            END IF;\n            SET a \u003d a - 1;\n        END WHILE masking;\n\n        RETURN ~result;\n    ELSE\n    SET bitmask \u003d pow(\n        2,\n        (32 - least(\n            cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),\n            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)\n        ))\n    ) - 1;\n\n    RETURN\n        inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d\n        inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;\n    END IF;\nEND","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"b514e56f504128551a4552c27e43f5b0e77288d5","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    DECLARE bitmask INT;"},{"line_number":37,"context_line":"    SET bitmask \u003d pow("},{"line_number":38,"context_line":"        2,"},{"line_number":39,"context_line":"        (32 - least("},{"line_number":40,"context_line":"            cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":41,"context_line":"            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)"},{"line_number":42,"context_line":"        ))"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_92ef5f1d","line":39,"in_reply_to":"bab6814e_b5f702d2","updated":"2016-05-26 09:56:21.000000000","message":"Dear Mr.Mike and Mr.Muller\n\nWelcome to my patch set, Mr.Muller\n\nThanks for your attention. I also wrote a idea for IPv6 base on Ipv4\n\nHere\u0027s it:\n\n\"\"\"\nadd_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject(\n    \"cidr_overlap(cidr1 varchar(30), ip_version_1 tinyint, \"\n    \"cidr2 varchar(30), ip_version_2 tinyint)\",\n    \"\"\"\n    RETURNS TINYINT\n    BEGIN\n    DECLARE bitmask INT;\n    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN\n    RETURN\n        inet6_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~(pow(2,\n            (32 - least(cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),\n             cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1) \u003d\n        inet6_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~(pow(2,\n            (32 - least(cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),\n            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1);\n    ELSE\n    SET bitmask \u003d pow(\n        2,\n        (32 - least(\n            cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),\n            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)\n        ))\n    ) - 1;\n\n    RETURN\n        inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d\n        inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;\n    END IF;\n    END\n    \"\"\"\n)\n\nadd_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject(\n    \"no_overlap_cidr_subnets\",\n    \"\"\"\n    BEFORE INSERT ON subnets\n    FOR EACH ROW\n    BEGIN\n      DECLARE msg VARCHAR(200);\n      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id\n        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN\n        SET msg \u003d CONCAT(\n            \u0027inserted subnet \u0027, NEW.cidr,\n            \u0027 conflicts with existing subnets\u0027);\n        SIGNAL sqlstate \u002745000\u0027\n            SET MESSAGE_TEXT \u003d msg;\n      END IF;\n    END\n    \"\"\"\n)\n\n\ndef upgrade():\n    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:\n        op.create_sp(add_stored_procedure_for_mysql)\n        op.create_trigger(add_trigger_for_mysql)\n    elif op.get_bind().engine.name \u003d\u003d \u0027postgresql\u0027:\n        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):\n            # (namnh): This feature is available for Postgresql 9.4 and\n            # higher versions.\n            op.execute(\"CREATE EXTENSION btree_gist\")\n            op.execute(\"ALTER TABLE subnets ADD CONSTRAINT \"\n                       \"no_overlap_cidr_subnets EXCLUDE USING \"\n                       \"gist((cast(cidr AS CIDR)) inet_ops WITH \u0026\u0026, \"\n                       \"network_id WITH \u003d)\")\n        else:\n            return\n    else:\n        return\n\n\"\"\"\n\nHowever, I have a things that the \"inet6_atom\" funtion is available for Mysql-5.6 and higher version, currently just there is mysql-5.5 on repo\u0027s Ubuntu. \u003d((. But how do you estimate this solution, could you give me some advices?","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"7068a7be60c5838f7bdda6ce19d1c2a9208dc77d","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        op.create_sp(add_stored_procedure_for_mysql)"},{"line_number":75,"context_line":"        op.create_trigger(add_trigger_for_mysql)"},{"line_number":76,"context_line":"    elif op.get_bind().engine.name \u003d\u003d \u0027postgresql\u0027:"},{"line_number":77,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":78,"context_line":"            # (namnh): This feature is available for Postgresql 9.4 and"},{"line_number":79,"context_line":"            # higher versions."},{"line_number":80,"context_line":"            op.execute(\"CREATE EXTENSION btree_gist\")"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_2b2e27fa","line":77,"updated":"2016-05-25 16:18:19.000000000","message":"perfect, very nice","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"b514e56f504128551a4552c27e43f5b0e77288d5","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        op.create_sp(add_stored_procedure_for_mysql)"},{"line_number":75,"context_line":"        op.create_trigger(add_trigger_for_mysql)"},{"line_number":76,"context_line":"    elif op.get_bind().engine.name \u003d\u003d \u0027postgresql\u0027:"},{"line_number":77,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":78,"context_line":"            # (namnh): This feature is available for Postgresql 9.4 and"},{"line_number":79,"context_line":"            # higher versions."},{"line_number":80,"context_line":"            op.execute(\"CREATE EXTENSION btree_gist\")"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_4f1b94ca","line":77,"in_reply_to":"bab6814e_2b2e27fa","updated":"2016-05-26 09:56:21.000000000","message":"Thanks for your appreciate.","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"7068a7be60c5838f7bdda6ce19d1c2a9208dc77d","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":78,"context_line":"            # (namnh): This feature is available for Postgresql 9.4 and"},{"line_number":79,"context_line":"            # higher versions."},{"line_number":80,"context_line":"            op.execute(\"CREATE EXTENSION btree_gist\")"},{"line_number":81,"context_line":"            op.execute(\"ALTER TABLE subnets ADD CONSTRAINT \""},{"line_number":82,"context_line":"                       \"no_overlap_cidr_subnets EXCLUDE USING \""},{"line_number":83,"context_line":"                       \"gist((cast(cidr AS CIDR)) inet_ops WITH \u0026\u0026, \""}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_8bfe3369","line":80,"updated":"2016-05-25 16:18:19.000000000","message":"do we need special user perms to run CREATE EXTENSION and/or does the PG user we run migrations with have this permission?","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"b514e56f504128551a4552c27e43f5b0e77288d5","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":78,"context_line":"            # (namnh): This feature is available for Postgresql 9.4 and"},{"line_number":79,"context_line":"            # higher versions."},{"line_number":80,"context_line":"            op.execute(\"CREATE EXTENSION btree_gist\")"},{"line_number":81,"context_line":"            op.execute(\"ALTER TABLE subnets ADD CONSTRAINT \""},{"line_number":82,"context_line":"                       \"no_overlap_cidr_subnets EXCLUDE USING \""},{"line_number":83,"context_line":"                       \"gist((cast(cidr AS CIDR)) inet_ops WITH \u0026\u0026, \""}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_0f5d0c47","line":80,"in_reply_to":"bab6814e_8bfe3369","updated":"2016-05-26 09:56:21.000000000","message":"No, we don\u0027t.\nPostgresql wrote: \"Loading an extension requires the same privileges that would be required to create its component objects. For most extensions this means superuser or database owner privileges are needed. The user who runs CREATE EXTENSION becomes the owner of the extension for purposes of later privilege checks, as well as the owner of any objects created by the extension\u0027s script.\" [1]\n\nHowever, I will verify this again by a test\n[1]https://www.postgresql.org/docs/9.1/static/sql-createextension.html","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":15471,"name":"Nguyen Phuong An","email":"annp.cs51@gmail.com","username":"An-FVL"},"change_message_id":"6ba2972bcfe7f3f5263969b2169e09468faf8297","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                       \"no_overlap_cidr_subnets EXCLUDE USING \""},{"line_number":83,"context_line":"                       \"gist((cast(cidr AS CIDR)) inet_ops WITH \u0026\u0026, \""},{"line_number":84,"context_line":"                       \"network_id WITH \u003d)\")"},{"line_number":85,"context_line":"        else:"},{"line_number":86,"context_line":"            return"},{"line_number":87,"context_line":"    else:"},{"line_number":88,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_fd005004","line":86,"range":{"start_line":85,"start_character":0,"end_line":86,"end_character":18},"updated":"2016-05-26 01:08:43.000000000","message":"I think no need \"return\" here.","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":15471,"name":"Nguyen Phuong An","email":"annp.cs51@gmail.com","username":"An-FVL"},"change_message_id":"0f6d5c685d95f38325f139aa676dc8508e6cec32","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                       \"gist((cast(cidr AS CIDR)) inet_ops WITH \u0026\u0026, \""},{"line_number":84,"context_line":"                       \"network_id WITH \u003d)\")"},{"line_number":85,"context_line":"        else:"},{"line_number":86,"context_line":"            return"},{"line_number":87,"context_line":"    else:"},{"line_number":88,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_acf058fe","line":86,"range":{"start_line":86,"start_character":12,"end_line":86,"end_character":18},"updated":"2016-05-26 04:03:00.000000000","message":"It should be better if we have warning a message at here. It looks like:\n\nLOG.warning(_LW(\"Preventing overlap CIDR feature is available for Postgresql\u003e\u003d9.4.0.\"))","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":15471,"name":"Nguyen Phuong An","email":"annp.cs51@gmail.com","username":"An-FVL"},"change_message_id":"0f6d5c685d95f38325f139aa676dc8508e6cec32","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        else:"},{"line_number":86,"context_line":"            return"},{"line_number":87,"context_line":"    else:"},{"line_number":88,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_ac3e9888","line":88,"range":{"start_line":88,"start_character":8,"end_line":88,"end_character":14},"updated":"2016-05-26 04:03:00.000000000","message":"Same above comment.\n\nLOG.warning(_LW(\"Preventing overlap CIDR feature is available for mysql \u0026 Posgresql\u003e\u003d9.4.0\"))","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"b514e56f504128551a4552c27e43f5b0e77288d5","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        else:"},{"line_number":86,"context_line":"            return"},{"line_number":87,"context_line":"    else:"},{"line_number":88,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_f26b4bb7","line":88,"range":{"start_line":88,"start_character":8,"end_line":88,"end_character":14},"in_reply_to":"bab6814e_ac3e9888","updated":"2016-05-26 09:56:21.000000000","message":"Thanks for your comment. I agree with you, we should inform user during upgrading. I will update next path set.","commit_id":"336769079056f4a190a26c9ffa0de86b9766e0db"},{"author":{"_account_id":15471,"name":"Nguyen Phuong An","email":"annp.cs51@gmail.com","username":"An-FVL"},"change_message_id":"4febc2506286ff7cf5998495ead6ed5e78c75c37","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    \"\"\""},{"line_number":35,"context_line":"    RETURNS TINYINT"},{"line_number":36,"context_line":"    BEGIN"},{"line_number":37,"context_line":"    DECLARE ipv61, ipv62 BIGINT;"},{"line_number":38,"context_line":"    DECLARE bitmask, division, modulo INT;"},{"line_number":39,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":40,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"}],"source_content_type":"text/x-python","patch_set":9,"id":"9abb7d3a_75f772f5","line":37,"range":{"start_line":37,"start_character":12,"end_line":37,"end_character":24},"updated":"2016-05-31 01:20:27.000000000","message":"It\u0027s better: ipv6_1, ipv6_2.","commit_id":"fb238cfec8db9ce0264aee71dc93c65262e06249"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"a9fcc876cd24bc3e83e74fbd9add98ccc7587ff7","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    \"cidr2 varchar(64), ip_version_2 int(11))\","},{"line_number":34,"context_line":"    \"\"\""},{"line_number":35,"context_line":"    RETURNS TINYINT"},{"line_number":36,"context_line":"    BEGIN"},{"line_number":37,"context_line":"    DECLARE ipv6_1, ipv6_2 BIGINT;"},{"line_number":38,"context_line":"    DECLARE bitmask, division, modulo INT;"},{"line_number":39,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"}],"source_content_type":"text/x-python","patch_set":10,"id":"9abb7d3a_ce5b04f5","line":36,"range":{"start_line":36,"start_character":4,"end_line":36,"end_character":9},"updated":"2016-05-31 16:10:04.000000000","message":"This solution will compare each bits between two CIDR from left to right. If there is not difference then this function return 0, it meant that no overlap CIDR.\n\nThere is especial things is: This function will compare 16 bits a time.","commit_id":"45299b9303e7748b5a56e795f9c2a23d8a112067"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"a9fcc876cd24bc3e83e74fbd9add98ccc7587ff7","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    DECLARE bitmask, division, modulo INT;"},{"line_number":39,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":40,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":41,"context_line":"    SET bitmask \u003d least(cast(substring_index(cidr1, \u0027/\u0027, -1)"},{"line_number":42,"context_line":"                                  as signed integer),"},{"line_number":43,"context_line":"                              cast(substring_index(cidr2, \u0027/\u0027, -1)"},{"line_number":44,"context_line":"                                  as signed integer));"}],"source_content_type":"text/x-python","patch_set":10,"id":"9abb7d3a_897bb68b","line":41,"range":{"start_line":41,"start_character":4,"end_line":41,"end_character":7},"updated":"2016-05-31 16:10:04.000000000","message":"This is purpose that this function just need to detect least number of bits from left.","commit_id":"45299b9303e7748b5a56e795f9c2a23d8a112067"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"a9fcc876cd24bc3e83e74fbd9add98ccc7587ff7","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    SET division \u003d bitmask DIV 16;"},{"line_number":46,"context_line":"    SET modulo \u003d bitmask % 16;"},{"line_number":47,"context_line":"    masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":48,"context_line":"        SET ipv6_1 \u003d CONV(substring_index(substring_index"},{"line_number":49,"context_line":"                                        (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 2);"},{"line_number":50,"context_line":"        SET ipv6_2 \u003d CONV(substring_index(substring_index"},{"line_number":51,"context_line":"                                        (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 2);"}],"source_content_type":"text/x-python","patch_set":10,"id":"9abb7d3a_a9f03a68","line":48,"updated":"2016-05-31 16:10:04.000000000","message":"At this point: It will convert from hexa to bin.\nFor example: \u0027abcd.de12\u0027 to \u0027abcd\u0027 then converting to bin \u00271010101111001101\u0027. In loop 2 times: \u0027abcd.de12\u0027 to \u0027de12\u0027 then convert to \u00271101111000010010\u0027","commit_id":"45299b9303e7748b5a56e795f9c2a23d8a112067"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"331789be69ac31b7c9ee5be93c298f274fd46a1e","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":"#"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"\"\"\"Add SP and trigger for Mysql and add gist for Postgresql"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Revision ID: 23c280e37c2c"},{"line_number":19,"context_line":"Revises: 30107ab6a3ee"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_5f28059a","line":16,"range":{"start_line":16,"start_character":7,"end_line":16,"end_character":9},"updated":"2016-06-02 04:37:59.000000000","message":"It is better to use a full spelling: stored procedure","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"cb0362deba76d2bb0c87e1b639a5899021b9b226","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":"#"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"\"\"\"Add SP and trigger for Mysql and add gist for Postgresql"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Revision ID: 23c280e37c2c"},{"line_number":19,"context_line":"Revises: 30107ab6a3ee"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_0760c8cd","line":16,"range":{"start_line":16,"start_character":7,"end_line":16,"end_character":9},"in_reply_to":"9abb7d3a_02fd816d","updated":"2016-06-06 10:06:22.000000000","message":"Done","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"2cd7a318725fd9b821fd15d4f77885fcf3070602","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":"#"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"\"\"\"Add SP and trigger for Mysql and add gist for Postgresql"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Revision ID: 23c280e37c2c"},{"line_number":19,"context_line":"Revises: 30107ab6a3ee"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_02fd816d","line":16,"range":{"start_line":16,"start_character":7,"end_line":16,"end_character":9},"in_reply_to":"9abb7d3a_5f28059a","updated":"2016-06-02 06:57:20.000000000","message":"Dear Motoki-san,\n\nFirstly, Thanks for your attention to my patch set. I will answer your questions, if I misundertand your comment, please let me know.\n\nIn this comment. That\u0027s ok, I will update in next patch set.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"331789be69ac31b7c9ee5be93c298f274fd46a1e","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from alembic import op"},{"line_number":24,"context_line":"from neutron._i18n import _LW"},{"line_number":25,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj"},{"line_number":26,"context_line":"from oslo_log import log as logging"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_3f2381be","line":26,"updated":"2016-06-02 04:37:59.000000000","message":"Please follow the guideline on import grouping.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"d061e0a4959e920a322ccc21d45028c7329f9ac1","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from alembic import op"},{"line_number":24,"context_line":"from neutron._i18n import _LW"},{"line_number":25,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj"},{"line_number":26,"context_line":"from oslo_log import log as logging"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_4411425d","line":26,"in_reply_to":"9abb7d3a_02d0e1c7","updated":"2016-06-04 12:07:08.000000000","message":"From various reasons, our hacking rule does not check import grouping.\nOur hacking rule guidelines [1] suggests it.\n\n  from alembic import op\n  from oslo_log import log as logging\n  \u003cblank line\u003e\n  from neutron._i18n import _LW\n  from neutron.db.migration.alembic_migrations imports replaceable_obj\n\n[1] http://docs.openstack.org/developer/hacking/#import-order-template","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"1fffd8e8df0289ab5cc96778ddcb8fcce63bdf81","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from alembic import op"},{"line_number":24,"context_line":"from neutron._i18n import _LW"},{"line_number":25,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj"},{"line_number":26,"context_line":"from oslo_log import log as logging"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_b0dc7b47","line":26,"in_reply_to":"9abb7d3a_02d0e1c7","updated":"2016-06-03 04:26:46.000000000","message":"Update:: Now, I understood your comment, I will update next patch. Thanks for your attention.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"2cd7a318725fd9b821fd15d4f77885fcf3070602","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from alembic import op"},{"line_number":24,"context_line":"from neutron._i18n import _LW"},{"line_number":25,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj"},{"line_number":26,"context_line":"from oslo_log import log as logging"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_02d0e1c7","line":26,"in_reply_to":"9abb7d3a_3f2381be","updated":"2016-06-02 06:57:20.000000000","message":"Are you mean that I should place \"import\" under \"revision\"? I did it but when I ran pep8, it always report at this point. That is reason I place it here.\n\nIf I don\u0027t catch your idea, please let me know.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"cb0362deba76d2bb0c87e1b639a5899021b9b226","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from alembic import op"},{"line_number":24,"context_line":"from neutron._i18n import _LW"},{"line_number":25,"context_line":"from neutron.db.migration.alembic_migrations import replaceable_obj"},{"line_number":26,"context_line":"from oslo_log import log as logging"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":29,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_41a000f5","line":26,"in_reply_to":"9abb7d3a_4411425d","updated":"2016-06-06 10:06:22.000000000","message":"Dear Motoki-san,\nThank you for your guide, Motoki-san. I already updated this in patch set 12.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":4656,"name":"Sean M. Collins","email":"sean@coreitpro.com","username":"scollins"},"change_message_id":"d29faf2f54449198f4c8a09cf68c95a9efbb807b","unresolved":false,"context_lines":[{"line_number":46,"context_line":"             cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1) \u003d"},{"line_number":47,"context_line":"        inet6_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~(pow(2,"},{"line_number":48,"context_line":"          (128 - least(cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":49,"context_line":"            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1);"},{"line_number":50,"context_line":"    ELSE"},{"line_number":51,"context_line":"    SET bitmask \u003d pow("},{"line_number":52,"context_line":"        2,"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_77630442","line":49,"updated":"2016-06-03 15:47:32.000000000","message":"This make my head hurt. Do we know for sure that this actually works, and do we really want to maintain this?","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"cb0362deba76d2bb0c87e1b639a5899021b9b226","unresolved":false,"context_lines":[{"line_number":46,"context_line":"             cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1) \u003d"},{"line_number":47,"context_line":"        inet6_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~(pow(2,"},{"line_number":48,"context_line":"          (128 - least(cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":49,"context_line":"            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1);"},{"line_number":50,"context_line":"    ELSE"},{"line_number":51,"context_line":"    SET bitmask \u003d pow("},{"line_number":52,"context_line":"        2,"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_6cfff301","line":49,"in_reply_to":"7aa08908_55f9fbc7","updated":"2016-06-06 10:06:22.000000000","message":"@Sean M.Collins\nDear Mr.Sean\n\n\u003e This make my head hurt. Do we know for sure that this actually works, and do we really want to maintain this?\n\nYes, I know. Actually, It makes my head hurt also. I will explain my algorithm in next patch. I am glad if you could spend a little time researching it. Thanks Mr.Sean\n\n@Akihiro Motoki\n\n\u003e I think Sean is talking about the testing method. How can we guarantee the algorithm works fine as expected?\n\nYes, I think so too. However I lack of experience for writting funional test, specially in case concurent request. Could you please give some key works to do this.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"d061e0a4959e920a322ccc21d45028c7329f9ac1","unresolved":false,"context_lines":[{"line_number":46,"context_line":"             cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1) \u003d"},{"line_number":47,"context_line":"        inet6_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~(pow(2,"},{"line_number":48,"context_line":"          (128 - least(cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":49,"context_line":"            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1);"},{"line_number":50,"context_line":"    ELSE"},{"line_number":51,"context_line":"    SET bitmask \u003d pow("},{"line_number":52,"context_line":"        2,"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_55f9fbc7","line":49,"in_reply_to":"7aa08908_a8f2876d","updated":"2016-06-04 12:07:08.000000000","message":"I think Sean is talking about the testing method. How can we guarantee the algorithm works fine as expected?","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"77f95b26fc6f84846f67e8834ab52993bb5db24b","unresolved":false,"context_lines":[{"line_number":46,"context_line":"             cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1) \u003d"},{"line_number":47,"context_line":"        inet6_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~(pow(2,"},{"line_number":48,"context_line":"          (128 - least(cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":49,"context_line":"            cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer)))) - 1);"},{"line_number":50,"context_line":"    ELSE"},{"line_number":51,"context_line":"    SET bitmask \u003d pow("},{"line_number":52,"context_line":"        2,"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_a8f2876d","line":49,"in_reply_to":"9abb7d3a_77630442","updated":"2016-06-04 08:48:24.000000000","message":"Wow. Hi Mr.Sean, welcome to my patch set. This is my luck. because I know that you have much experience for IPv6, don\u0027t you?\n\nThanks for this comment. While reply your comment, I found a problem with this algorithm, I will verify it. Do you have any suggestion to detect overlap IPv6 in Database?","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"331789be69ac31b7c9ee5be93c298f274fd46a1e","unresolved":false,"context_lines":[{"line_number":85,"context_line":")"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"def upgrade():"},{"line_number":89,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":90,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (5, 6, 0):"},{"line_number":91,"context_line":"            # NOTE(namnh): This feature is available for Mysql 5.6 and"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_e40a0d1f","line":88,"range":{"start_line":88,"start_character":4,"end_line":88,"end_character":14},"updated":"2016-06-02 04:37:59.000000000","message":"This upgrade script skips installation of stored procedure if DB version does not satisfy the requirements.\n\nIf an operator wants to upgrade his database laster but he wants to upgrade to Newton, what can he do? How can he install this stored procedure later?\n\nI think it is an important point to be discussed.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"cb0362deba76d2bb0c87e1b639a5899021b9b226","unresolved":false,"context_lines":[{"line_number":85,"context_line":")"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"def upgrade():"},{"line_number":89,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":90,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (5, 6, 0):"},{"line_number":91,"context_line":"            # NOTE(namnh): This feature is available for Mysql 5.6 and"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_0cc62f67","line":88,"range":{"start_line":88,"start_character":4,"end_line":88,"end_character":14},"in_reply_to":"7aa08908_75c5175a","updated":"2016-06-06 10:06:22.000000000","message":"In next patch set. For mysql, I modified the algorithm so we can apply any version.\n\nFor Postgresql, I am finding a solution, if I have any information, I will report to you. Are you ok?.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"d061e0a4959e920a322ccc21d45028c7329f9ac1","unresolved":false,"context_lines":[{"line_number":85,"context_line":")"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"def upgrade():"},{"line_number":89,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":90,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (5, 6, 0):"},{"line_number":91,"context_line":"            # NOTE(namnh): This feature is available for Mysql 5.6 and"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_75c5175a","line":88,"range":{"start_line":88,"start_character":4,"end_line":88,"end_character":14},"in_reply_to":"9abb7d3a_023aa1e6","updated":"2016-06-04 12:07:08.000000000","message":"\u003e \u003e If an operator wants to upgrade his database laster but he wants to upgrade to Newton, what can he do? How can he install this stored procedure later?\n\n\u003e I also report message to user so they will know what happend. User can update one this pach. We had document to do it.\n\nSo, do you plan to provide a way to install the stored procedure proposed in this patch later? What I mean is to upgrade Neutron without the stored procedure (to continue to use an old version of DB software, then upgrade DB software later when an operator like and finally deploy your stored procedure later.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"2cd7a318725fd9b821fd15d4f77885fcf3070602","unresolved":false,"context_lines":[{"line_number":85,"context_line":")"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"def upgrade():"},{"line_number":89,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":90,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (5, 6, 0):"},{"line_number":91,"context_line":"            # NOTE(namnh): This feature is available for Mysql 5.6 and"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_023aa1e6","line":88,"range":{"start_line":88,"start_character":4,"end_line":88,"end_character":14},"in_reply_to":"9abb7d3a_e40a0d1f","updated":"2016-06-02 06:57:20.000000000","message":"\u003e This upgrade script skips installation of stored procedure if DB version does not satisfy the requirements.\n\nYes, you are quite right, this patch focus on DB backend. As you saw, I need to cover each DB including Mysql, Postgresql, I didn\u0027t change coding in Neutron very much.\n\n\u003e If an operator wants to upgrade his database laster but he wants to upgrade to Newton, what can he do? How can he install this stored procedure later?\n\nI also report message to user so they will know what happend. User can update one this pach. We had document to do it.\n\n\u003e I think it is an important point to be discussed.\n\nYes, I fully agree with you. We will discuss about this more, currently I am discussing with Mr.Mike about those","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"331789be69ac31b7c9ee5be93c298f274fd46a1e","unresolved":false,"context_lines":[{"line_number":88,"context_line":"def upgrade():"},{"line_number":89,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":90,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (5, 6, 0):"},{"line_number":91,"context_line":"            # NOTE(namnh): This feature is available for Mysql 5.6 and"},{"line_number":92,"context_line":"            # higher version"},{"line_number":93,"context_line":"            op.create_sp(add_stored_procedure_for_mysql_higher_5_6)"},{"line_number":94,"context_line":"            op.create_trigger(add_trigger_for_mysql_higher_5_6)"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_7a5cf718","line":91,"range":{"start_line":91,"start_character":57,"end_line":91,"end_character":67},"updated":"2016-06-02 04:37:59.000000000","message":"Similar feeling as for postgresql, but mysql 5.6 was released more than two years ago, so I am not sure it is a problem.\nHowever, we should keep it in my mind that we don\u0027t upgrade DB server so aggressively.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"cb0362deba76d2bb0c87e1b639a5899021b9b226","unresolved":false,"context_lines":[{"line_number":88,"context_line":"def upgrade():"},{"line_number":89,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":90,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (5, 6, 0):"},{"line_number":91,"context_line":"            # NOTE(namnh): This feature is available for Mysql 5.6 and"},{"line_number":92,"context_line":"            # higher version"},{"line_number":93,"context_line":"            op.create_sp(add_stored_procedure_for_mysql_higher_5_6)"},{"line_number":94,"context_line":"            op.create_trigger(add_trigger_for_mysql_higher_5_6)"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_875cb826","line":91,"range":{"start_line":91,"start_character":57,"end_line":91,"end_character":67},"in_reply_to":"7aa08908_55e73b12","updated":"2016-06-06 10:06:22.000000000","message":"Yes, I know, I am in dificult. Currently, in my knowledge there will be two solutions to fix this bug:\n\n1. Preventing: when there are concurent requests to create subnet on *one* network and I had a patch set for this [1]. But Mr.Kevin doesn\u0027t like the solution. Can\u0027t you see and estimate the patch.\n\n2. Add condition to DB. It is this pach set.\n\n[1] https://review.openstack.org/#/c/267470/","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"2cd7a318725fd9b821fd15d4f77885fcf3070602","unresolved":false,"context_lines":[{"line_number":88,"context_line":"def upgrade():"},{"line_number":89,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":90,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (5, 6, 0):"},{"line_number":91,"context_line":"            # NOTE(namnh): This feature is available for Mysql 5.6 and"},{"line_number":92,"context_line":"            # higher version"},{"line_number":93,"context_line":"            op.create_sp(add_stored_procedure_for_mysql_higher_5_6)"},{"line_number":94,"context_line":"            op.create_trigger(add_trigger_for_mysql_higher_5_6)"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_fd973c37","line":91,"range":{"start_line":91,"start_character":57,"end_line":91,"end_character":67},"in_reply_to":"9abb7d3a_7a5cf718","updated":"2016-06-02 06:57:20.000000000","message":"\u003e However, we should keep it in my mind that we don\u0027t upgrade DB server so aggressively.\n\nI know that the problem is related to DB which is difficult and the core-review like you will have to discuss to others. However in case neutron server active-active (two neutron servers run at the sam time), there is only one common point, that is DB. Let\u0027s image that if we created two subnet with overlap CIDR, there will be many VM with same IP.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"d061e0a4959e920a322ccc21d45028c7329f9ac1","unresolved":false,"context_lines":[{"line_number":88,"context_line":"def upgrade():"},{"line_number":89,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":90,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (5, 6, 0):"},{"line_number":91,"context_line":"            # NOTE(namnh): This feature is available for Mysql 5.6 and"},{"line_number":92,"context_line":"            # higher version"},{"line_number":93,"context_line":"            op.create_sp(add_stored_procedure_for_mysql_higher_5_6)"},{"line_number":94,"context_line":"            op.create_trigger(add_trigger_for_mysql_higher_5_6)"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_55e73b12","line":91,"range":{"start_line":91,"start_character":57,"end_line":91,"end_character":67},"in_reply_to":"9abb7d3a_fd973c37","updated":"2016-06-04 12:07:08.000000000","message":"\u003e However, we should keep it in my mind that we don\u0027t upgrade DB server so aggressively.\n\nI should rephrase \"we don\u0027t upgrade ...\" to \"operators don\u0027t upgrade\".\n\nI am just talking about the minimum requirement of DB software version. Upgrading DB software in production requires another kind of intensive upgrade testing. I think this makes it harder to upgrade OpenStack.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"331789be69ac31b7c9ee5be93c298f274fd46a1e","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                            \"if you want to use this feature.\"))"},{"line_number":99,"context_line":"    elif op.get_bind().engine.name \u003d\u003d \u0027postgresql\u0027:"},{"line_number":100,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":101,"context_line":"            # NOTE(namnh): This feature is available for Postgresql 9.4 and"},{"line_number":102,"context_line":"            # higher versions."},{"line_number":103,"context_line":"            op.execute(\"CREATE EXTENSION btree_gist\")"},{"line_number":104,"context_line":"            op.execute(\"ALTER TABLE subnets ADD CONSTRAINT \""}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_1a1fab5b","line":101,"range":{"start_line":101,"start_character":57,"end_line":101,"end_character":71},"updated":"2016-06-02 04:37:59.000000000","message":"I am just afraid this requirement is too tight.\nUbuntu 14.04 provides PostgreSQL 9.3.\n\nWhat happens if postgresql older than 9.4.0?\nDoes this bug remain unfiexed?","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"2cd7a318725fd9b821fd15d4f77885fcf3070602","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                            \"if you want to use this feature.\"))"},{"line_number":99,"context_line":"    elif op.get_bind().engine.name \u003d\u003d \u0027postgresql\u0027:"},{"line_number":100,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":101,"context_line":"            # NOTE(namnh): This feature is available for Postgresql 9.4 and"},{"line_number":102,"context_line":"            # higher versions."},{"line_number":103,"context_line":"            op.execute(\"CREATE EXTENSION btree_gist\")"},{"line_number":104,"context_line":"            op.execute(\"ALTER TABLE subnets ADD CONSTRAINT \""}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_9d1d5075","line":101,"range":{"start_line":101,"start_character":57,"end_line":101,"end_character":71},"in_reply_to":"9abb7d3a_1a1fab5b","updated":"2016-06-02 06:57:20.000000000","message":"In Postgresql, I use \"gist\" feature. Unlucky, Gist in Postgre9.3 don\u0027t support \"cidr\" type. I and Mr.Mike try to think a solution for Postgre older than 9.4. But it is difficult. You can see last Mike\u0027s comment.\n\nMore over, trigger in Postgre doesn\u0027t solve this bug. Because Postgre uses \"read commited\" isolation level.","commit_id":"8fcaba53a6498b0fe7bb9c949b0ad3a0250c98c5"}],"neutron/db/migration/alembic_migrations/versions/newton/expand/2702ea9d9f73__create_funtion_to_db.py":[{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"38fd713350081db219fe557a3d02a00b4406f1c3","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":"#"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"\"\"\"_create_funtion_to_db"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Revision ID: 2702ea9d9f73"},{"line_number":19,"context_line":"Revises: d3435b514502"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_6b1fea5b","line":16,"range":{"start_line":16,"start_character":3,"end_line":16,"end_character":24},"updated":"2016-05-12 14:23:31.000000000","message":"Use this comment: \"Add SP and trigger for CIDR overlap\"","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"},{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"38fd713350081db219fe557a3d02a00b4406f1c3","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from alembic import context"},{"line_number":24,"context_line":"from alembic import op"},{"line_number":25,"context_line":"from neutron.db.migration.alembic_migrations.\\"},{"line_number":26,"context_line":"    replaceable_obj import ReplaceableObject"},{"line_number":27,"context_line":"from neutron.db.migration.connection import DBConnection"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"# revision identifiers, used by Alembic."}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_8b64cee5","line":26,"updated":"2016-05-12 14:23:31.000000000","message":"Import the module, not the object.","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"2de3b8ba0ade380363864888a0978284bc3f9077","unresolved":false,"context_lines":[{"line_number":31,"context_line":"down_revision \u003d \u0027d3435b514502\u0027"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def get_db_backend():"},{"line_number":35,"context_line":"    config \u003d context.config"},{"line_number":36,"context_line":"    neutron_config \u003d config.neutron_config"},{"line_number":37,"context_line":"    connection \u003d config.attributes.get(\u0027connection\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_5f22ad02","line":34,"updated":"2016-05-12 11:40:40.000000000","message":"this only has to be:\n\n    op.get_bind().engine.name","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"},{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"38fd713350081db219fe557a3d02a00b4406f1c3","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        return conn.engine.name"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"add_customer_sp_for_mysql \u003d ReplaceableObject("},{"line_number":43,"context_line":"    \"cidr_overlap(cidr1 varchar(30), cidr2 varchar(30))\","},{"line_number":44,"context_line":"    \"\"\""},{"line_number":45,"context_line":"    RETURNS TINYINT"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_ebb8fa2c","line":42,"range":{"start_line":42,"start_character":0,"end_line":42,"end_character":25},"updated":"2016-05-12 14:23:31.000000000","message":"add_stored_procedure_for_mysql","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"},{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"38fd713350081db219fe557a3d02a00b4406f1c3","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    \"\"\""},{"line_number":61,"context_line":")"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"add_customer_trigger_for_mysql \u003d ReplaceableObject("},{"line_number":64,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":65,"context_line":"    \"\"\""},{"line_number":66,"context_line":"    BEFORE INSERT ON subnets"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_6bf24a08","line":63,"range":{"start_line":63,"start_character":0,"end_line":63,"end_character":30},"updated":"2016-05-12 14:23:31.000000000","message":"add_trigger_for_mysql","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"},{"author":{"_account_id":6524,"name":"Henry Gessau","email":"HenryG@gessau.net","username":"gessau"},"change_message_id":"38fd713350081db219fe557a3d02a00b4406f1c3","unresolved":false,"context_lines":[{"line_number":79,"context_line":"    \"\"\""},{"line_number":80,"context_line":")"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"add_customer_sp_for_postgresql \u003d ReplaceableObject()"},{"line_number":83,"context_line":"add_customer_trigger_for_postgresql \u003d ReplaceableObject()"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":5,"id":"dab17558_4b45c615","line":83,"range":{"start_line":82,"start_character":0,"end_line":83,"end_character":57},"updated":"2016-05-12 14:23:31.000000000","message":"I assume these will be written in an upcoming patch set? Please use names like I suggested above for mysql.","commit_id":"9ff898078048eccd5cb057eb3c9eab0139b5fb77"}],"neutron/db/migration/alembic_migrations/versions/newton/expand/5bbf1e0b1774_add_stored_procedure_and_trigger_for_.py":[{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"d17d166634f66f6c2da1fe114e51edbab6c71524","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    SET netmask \u003d least("},{"line_number":53,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":54,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":55,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":56,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":57,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":58,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"}],"source_content_type":"text/x-python","patch_set":19,"id":"7aa08908_bf3fa385","line":55,"range":{"start_line":55,"start_character":7,"end_line":55,"end_character":46},"updated":"2016-06-14 08:22:13.000000000","message":"@Michael Bayer\n\nCould I discuss this algorithm for IPv6 with you. Essentially, it base on IPv4. But there is a small difference that Mysql don\u0027t support to compare 128 bits, more over there is not Numeric Types with 128 bits for store, so I have to some times with 16 bits for each.\n\nIn Mysql_5.6: There is inet6_aton function for IPv6. I do want to use this function and combine with \"bitmask\" 128 bits. This will increase performance. Do you have any suggestion for this.","commit_id":"05f9a2a81b3981e111a25b5fe8cb850481eb13e1"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"5dc750a23cb3fdc5df58edb771125455a5aced48","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":119,"context_line":"            # NOTE(namnh): This feature is available for Postgresql 9.4 and"},{"line_number":120,"context_line":"            # higher versions."},{"line_number":121,"context_line":"            op.execute(\"CREATE EXTENSION IF NOT EXISTS btree_gist\")"},{"line_number":122,"context_line":"            op.execute(\"ALTER TABLE subnets ADD CONSTRAINT \""},{"line_number":123,"context_line":"                       \"no_overlap_cidr_subnets EXCLUDE USING \""},{"line_number":124,"context_line":"                       \"gist((cast(cidr AS CIDR)) inet_ops WITH \u0026\u0026, \""}],"source_content_type":"text/x-python","patch_set":24,"id":"1aa78d24_f78db431","line":121,"range":{"start_line":121,"start_character":12,"end_line":121,"end_character":67},"updated":"2016-07-07 12:26:23.000000000","message":"Hello Mr.Mike\n\nI wrote function-test. But unlucky, for postgresql, the system cannot create extersion because the user for funtional-test doesn\u0027t have superuser permision -:(. Here is log: [1], if I set superuser permision for the user then it\u0027s ok. Do you have advices for this case ?\n\n[1] http://paste.openstack.org/show/526917/","commit_id":"44cc18211229f1d58e1666f6dc0118fbe3968c71"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"9f87bb8691defaff2fe4fe5b30a4b9960974439f","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_9377b69e","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"updated":"2016-07-19 11:15:40.000000000","message":"I think we should avoid using non-portable things like triggers as almost every DB backend has its\u0027 own language for them (same as in [1]).\n\n[1] https://review.openstack.org/#/c/323807/","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"b4b26bf9b544f23e97bc1940ae92b11bb2b64e2e","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_c9a8b1de","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_097065db","updated":"2016-07-22 06:39:39.000000000","message":"@Ilya Chukhnakov\n\n\u003e I wonder if we can use recently introduced revision numbers [1] on Network for that (no model changes needed).\n\nI would like to update a formation to you. After dicussion with Kevin, his patch set [1] doesn\u0027t fix this bug [2] at Apr 14 6:24 PM.\n\nOne more things, Possible to fix this bug base on his patch *if* we have to add some lines of code. But he said that he prefer this solution and IMO, I also prefer this one. \n\n[1] https://review.openstack.org/#/c/303966/\n[2] https://review.openstack.org/#/c/267470/","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"98da335334c9fac30c8b7866a5851c8a858fe416","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_0f5b45f7","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_097065db","updated":"2016-07-20 16:38:58.000000000","message":"It looks like Kevin Benton raised this on Apr 12 in https://review.openstack.org/#/c/267470/17, although it wasn\u0027t indicated that this column could be repurposed to be used for something slightly outside of the ORM\u0027s direct handling of it (that is, as a token indicative of the state of a related record collection); it can be used in this way, but has the same disadvantage of the GUID approach is that it is a coarse-grained, optimistic lock that under high concurrency will lead to contention and retries.   That is, it scales poorly.   It is more coarsely-grained than the GUID approach because this number gets bumped anytime a change is made to the Network record.  I recommend that thread in any case to see how we got here.\n\nLook at it this way.  If MySQL provided out-of-the-box CIDR datatypes and overlap functions, the way Postgresql does already, just adding a simple trigger and a GIST constraint for PG would be non-controversial, right?     The CIDR function here is entirely agnostic of Neutron and once we get one that is fully tested for ipv4/v6, it can go anywhere and never has to be looked at again.  If someone published an OSS package of CIDR functions for MySQL upstream, it would be a simple dependency (and probably would get used a lot of other places too).","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"e33a4cdae27fe6880aac23586e3d0c0be9e01be7","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_74fa9544","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_0f5b45f7","updated":"2016-07-20 18:05:01.000000000","message":"Ok, I need to clarify my original statement. I\u0027m not totally against the use of triggers/stored procedures (tho many years of DBA/DBD experience make me hate them with passion for how often they are misused). But having them declared like in this patch (i.e. as strings) seems to be way off.\n\nI think for the constraint-trigger we need some kind of anti-FK construct (i.e. \u0027if not exists\u0027). Something that we can feed the \u0027select\u0027 part of that trigger as a SQLA expression and it would build a trigger body in a portable way for us (based on the DB engine in use). That would come handy in other places too (e.g. Trunk/SubPort port_id uniqueness across two tables [1]).\n\nAs for the \u0027cidr_overlap\u0027 I don\u0027t see a clean way to solve that problem now. It does seem to me that the problem is in the model (cidr column being a string type), but it\u0027s probably too late to fix that.\n\n[1] https://github.com/openstack/neutron/blob/master/neutron/services/trunk/models.py#L81","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"b4b26bf9b544f23e97bc1940ae92b11bb2b64e2e","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_c9cd51b9","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_17c99226","updated":"2016-07-22 06:39:39.000000000","message":"@Michael Bayer\n\n\u003e  Whether the whole feature has to be delayed until oslo.\u003csomething\u003e can invent this whole thing upstream is then the issue.\n\nThank you for your support, if there are any work that I can do for you, please tell me. I will. :)","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"b4b26bf9b544f23e97bc1940ae92b11bb2b64e2e","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_f99d880a","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_272be895","updated":"2016-07-22 06:39:39.000000000","message":"@Ilya Chukhnakov\n\n\u003e I suggest that instead of \u0027cidr_overlap\u0027 function and the trigger we could add a numeric CIDR representation to the \u0027subnets\u0027 table (i.e. subnet_begin, subnet_end [*]). Then we could \u0027select for update\u0027 the range based on subnet_begin/subnet_end range to check for conflicts.\n\nThanks for your suggestion, I understood what you mean but in this case, your one doesn\u0027t apply. More over, \"SELECT FOR UPDATE\" is similar to\"compare-and-swap\", this method need one common point to update, but we don\u0027t any commont point before creating subnet. \nTo do this, we need to create a common point, that\u0027s another my patch set. Image that if this solution can be applied then we won\u0027t need the \"_validate_subnet_cidr\" function, especially we prevent overlap CIDR in case concurrent request. That\u0027s good, right? :-D","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"43fe0a1508066c9587cd3a806df70eeb088e10ad","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_35d785ee","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_272be895","updated":"2016-07-20 15:31:02.000000000","message":"This trigger guards against conflicting INSERTs of new rows.  SELECT FOR UPDATE, in the SQL standard sense, only locks existing rows and does not impact incoming rows.  While MySQL\u0027s InnoDB may be able to utilize a gap lock here if the right indexes are placed on the values, Postgresql doesn\u0027t do this; InnoDB\u0027s gap lock is not a standard feature.   Using SELECT FOR UPDATE in this way is non-portable.  InnoDB\u0027s gap locks also require REPEATABLE READ isolation, which is MySQL\u0027s default but there have been issues in the past where changing this isolation has been discussed, I\u0027m not sure if Neutron ever implemented this but some of the compare-and-swap schemes relied upon READ COMMITTED in order to see changes to a row occurring between SELECTs (the ability to do isolation-per-transaction was enhanced in SQLAlchemy to allow more localized switching of isolation levels).\n\nWhile the integer range could be a replacement for the availability of CIDR math functions on MySQL, IMO it\u0027s not a replacement for the use of a constraint of some kind, at least on the Postgresql side.  \n\nAlso, the integer range approach would increase complexity due to the requirement that schema and data migrations support \"online\" capability.  The new columns would not be usable until all consuming neutron services were upgraded to the new code and all data has been migrated (any old neutron services still running during this might insert new subnet rows without the integer values).  Ironically the best way to migrate the table to have the new integers in all cases even while older neutron APIs might be hitting the table with new inserts would be.... to use an INSERT trigger ;)\n\nI think if adding new columns were going to be part of this then the original \"add-a-GUID-lock-to-network\" approach in https://review.openstack.org/#/c/267470/17/neutron/db/db_base_plugin_v2.py is a much lower impact, as it doesn\u0027t require a data migration.","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"997502532b8cf09a962cede1f3a58bd39a877a74","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_097065db","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_35d785ee","updated":"2016-07-20 16:17:08.000000000","message":"\u003e original \"add-a-GUID-lock-to-network\"\n\nI wonder if we can use recently introduced revision numbers [1] on Network for that (no model changes needed).\n\n[1] https://review.openstack.org/#/c/328185/5/neutron/db/model_base.py@174","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"3b8a77915696b5a494ab1d279bda324cd11d6a77","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_17c99226","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_57802af7","updated":"2016-07-20 22:10:54.000000000","message":"ok, then we\u0027ve been saying the same thing on this, including as we were yesterday.  everyone agrees this is too much code right in models.py.   Whether the whole feature has to be delayed until oslo.\u003csomething\u003e can invent this whole thing upstream is then the issue.","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"f461a53ad470f347e5507d62618b51bb87b79b4d","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_272be895","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_723033e9","updated":"2016-07-20 11:17:38.000000000","message":"The problem as I see it is due to CIDR being stored as a string which prevents us from using it efficiently.\n\nI suggest that instead of \u0027cidr_overlap\u0027 function and the trigger we could add a numeric CIDR representation to the \u0027subnets\u0027 table (i.e. subnet_begin, subnet_end [*]). Then we could \u0027select for update\u0027 the range based on subnet_begin/subnet_end range to check for conflicts.\n\n[*] we\u0027ll probably have represent each of subnet_begin/subnet_end as 2 8-byte integers to support 128 bits of ipv6. also the ipv6 \u0027math\u0027 would work for ipv4 as ipv4 would be stored as ipv6 padded with 0s.","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"b6b133518901ad6d75bcb08cae6af0072c622849","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_ed287435","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_74fa9544","updated":"2016-07-20 19:14:11.000000000","message":"a nice SQLAlchemy \"trigger\" construct might look nice, but the implementation of using such a trigger on MySQL would still be entirely MySQL-specific, because as noted earlier, the same trigger here on Postgresql does not produce the desired effect.  That \"string\" that\u0027s there has no need to work on any other platform.   If it ever did, then that would be the time to produce a fine-grained abstraction over trigger declarations.    There certainly *is* a problem that these strings are stated *twice* in the codebase, and I\u0027m not crazy about that at all but I\u0027d need to think of a way to allow both the alembic migration to work and exist distinctly from a fixed model structure that invokes during a create_all().\n\nThere\u0027s a reason SQLAlchemy doesn\u0027t have a \"trigger\" construct and it\u0027s because SQL triggers are crossing the bridge into imperative programming instead of declarative.  Once your SQL construct has to be concerned with \"steps to take\" vs. \"here\u0027s what I want\", the whole \"SQL abstraction layer\" idea loses steam very fast, and in the real world you\u0027d need something different enough on each backend that you might as well just use the DDL() construct, which is why it\u0027s there.   It\u0027s not that a sqlalchemy.Trigger() construct would never be part of SQLAlchemy, it\u0027s just that the interest in such a concept is low because there\u0027s not much of a payoff.\n\nThe abstraction that IMO is more appropriate here, and I will reiterate eventually (or sooner) won\u0027t be in Neutron at all but in oslo.db or elsewhere, is a backend-agnostic \"overlap constraint\", or even just a \"functional constraint\".  Since that is what we are building here.  If MySQL actually supported CHECK constraints, we might not be using a trigger.   This abstraction to start off with would probably even be hardcoded to the CIDR range idea, because that\u0027s all that\u0027s needed.  A later iteration can open it up for other kinds of conditions.   This is a coarse-grained abstraction which will be more effective and low-risk than implementing a fine-grained abstraction over trigger and stored procedure languages.","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"d9300403d9bc1b5b385835e7387518e7e96e25d7","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_723033e9","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_9377b69e","updated":"2016-07-19 13:54:56.000000000","message":"Another problem is the code is hard to maintain. Not everyone is aware how to code in SQL beyond simple statements.","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"},{"author":{"_account_id":21273,"name":"Ilya Chukhnakov","email":"Ilya.chukhnakov@gmail.com","username":"ichukhnakov"},"change_message_id":"2526f3a7d51d511f70a58c4aba94a1beb525f6e6","unresolved":false,"context_lines":[{"line_number":33,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":37,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":38,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":"    RETURNS TINYINT"},{"line_number":41,"context_line":"    BEGIN"},{"line_number":42,"context_line":"    -- This function will compare each bit from left to right, if there is any"},{"line_number":43,"context_line":"    -- difference then it will return no overlap and vice versa. And the number"},{"line_number":44,"context_line":"    -- of bit for comparing is the smallest of two netmasks."},{"line_number":45,"context_line":"    -- The result of this function is 0 or 1"},{"line_number":46,"context_line":"    -- 1: there is overlap."},{"line_number":47,"context_line":"    -- 0: there is not overlap."},{"line_number":48,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":49,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":50,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":51,"context_line":"    SET netmask \u003d least("},{"line_number":52,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":53,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":54,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":55,"context_line":"        -- NOTE(namnh): Because Mysql does not support to compare with 128 bits"},{"line_number":56,"context_line":"        -- more over there is not Numeric Types with 128 bits for store,"},{"line_number":57,"context_line":"        -- so I have to some times with 16 bits for each."},{"line_number":58,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":59,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":60,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":61,"context_line":"            -- The \u0027COALESCE\u0027 function will guarantee that ipv6_1 and ipv6_2"},{"line_number":62,"context_line":"            -- have not NULL."},{"line_number":63,"context_line":"            SET ipv6_1 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":64,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":65,"context_line":"            SET ipv6_2 \u003d COALESCE(CONV(substring_index(substring_index"},{"line_number":66,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10), 0);"},{"line_number":67,"context_line":"            IF (division !\u003d 0) THEN"},{"line_number":68,"context_line":"                IF (ipv6_1 !\u003d ipv6_2) THEN"},{"line_number":69,"context_line":"                    RETURN 0;"},{"line_number":70,"context_line":"                    LEAVE masking;"},{"line_number":71,"context_line":"                END IF;"},{"line_number":72,"context_line":"            ELSE"},{"line_number":73,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":74,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":75,"context_line":"            END IF;"},{"line_number":76,"context_line":"            SET tmp \u003d tmp + 1;"},{"line_number":77,"context_line":"            SET division \u003d division - 1;"},{"line_number":78,"context_line":"        END WHILE masking;"},{"line_number":79,"context_line":"    ELSEIF (ip_version_1 \u003d 4 AND ip_version_2 \u003d 4) THEN"},{"line_number":80,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":81,"context_line":"        RETURN"},{"line_number":82,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":83,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":84,"context_line":"    ELSE"},{"line_number":85,"context_line":"        RETURN 0;"},{"line_number":86,"context_line":"    END IF;"},{"line_number":87,"context_line":"    END"},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":")"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"add_trigger_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":93,"context_line":"    \"no_overlap_cidr_subnets\","},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":"    BEFORE INSERT ON subnets"},{"line_number":96,"context_line":"    FOR EACH ROW"},{"line_number":97,"context_line":"    BEGIN"},{"line_number":98,"context_line":"      DECLARE msg VARCHAR(200);"},{"line_number":99,"context_line":"      IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id"},{"line_number":100,"context_line":"        AND cidr_overlap(cidr, ip_version, NEW.cidr, NEW.ip_version))) THEN"},{"line_number":101,"context_line":"        SET msg \u003d CONCAT("},{"line_number":102,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"},{"line_number":103,"context_line":"            \u0027 conflicts with existing subnets\u0027);"},{"line_number":104,"context_line":"        SIGNAL sqlstate \u002745000\u0027"},{"line_number":105,"context_line":"            SET MESSAGE_TEXT \u003d msg;"},{"line_number":106,"context_line":"      END IF;"},{"line_number":107,"context_line":"    END"},{"line_number":108,"context_line":"    \"\"\""},{"line_number":109,"context_line":")"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"def upgrade():"}],"source_content_type":"text/x-python","patch_set":27,"id":"dada55a8_57802af7","line":109,"range":{"start_line":36,"start_character":0,"end_line":109,"end_character":1},"in_reply_to":"dada55a8_ed287435","updated":"2016-07-20 22:00:37.000000000","message":"@Michael, I\u0027m not talking about creating a generic imperative \"trigger\" abstraction (that would be kind of crazy) in SQLA, but a *declarative* \"check constraint\" (limited to checking \"not exists(select ...)\"). Something that would have the same syntax in the model for all engines, but the implementation could be different for each engine (e.g. a trigger for MySQL and maybe even some python code for some other engine). I think that is pretty close to the \"functional constraint\" that you mentioned.\n\nThe idea is to separate the model from implementation details. Because the proposed changes to the model module [1] do look like a workaround to me and are not readable at all.\n\n[1] https://review.openstack.org/#/c/314054/27/neutron/db/models_v2.py","commit_id":"90f46e235672d3917015e5c49aa0513fb1de7ba9"}],"neutron/db/migration/alembic_migrations/versions/newton/expand/7c352ad46f27_add_stored_procedure_and_trigger_for_.py":[{"author":{"_account_id":15471,"name":"Nguyen Phuong An","email":"annp.cs51@gmail.com","username":"An-FVL"},"change_message_id":"176e6c83642d9cbfb738a1824ad710eb77548eca","unresolved":false,"context_lines":[{"line_number":34,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":38,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":39,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":40,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":18,"id":"7aa08908_7960bba5","line":37,"updated":"2016-06-14 07:28:03.000000000","message":"Please add your idea as Sean\u0027s comments at patch-set 12.","commit_id":"34322e4fff72a5a49932d5f4b701fdc84ed35365"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"22976d3bffb737827d531a974872694ef4cf42dc","unresolved":false,"context_lines":[{"line_number":34,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":38,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":39,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":40,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":18,"id":"7aa08908_9f9aa760","line":37,"in_reply_to":"7aa08908_7960bba5","updated":"2016-06-14 08:27:28.000000000","message":"Oh. Thanks for your reminder. I haved update new patch with your comment. Could you check it.","commit_id":"34322e4fff72a5a49932d5f4b701fdc84ed35365"}],"neutron/db/migration/alembic_migrations/versions/newton/expand/be383e41a455__create_funtion_to_db.py":[{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"597ced2e455cafcbeb51d679442729cf0578a002","unresolved":false,"context_lines":[{"line_number":77,"context_line":")"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"class ReversibleOp(MigrateOperation):"},{"line_number":81,"context_line":"    def __init__(self, target):"},{"line_number":82,"context_line":"        self.target \u003d target"},{"line_number":83,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"dab17558_4a3bbcd1","line":80,"updated":"2016-05-09 12:55:40.000000000","message":"OK I see you\u0027ve implemented the recipe at http://alembic.readthedocs.io/en/latest/cookbook.html#replaceable-objects and that\u0027s definitely a nice to have if we are starting to use triggers and stored fucntions.  However, these are structures that are generic and established as part of the alembic infrastructure itself, are to be used by any number of migration files, so they don\u0027t belong here - we don\u0027t want to be repeating all this boilerplate in every migration that deals with triggers / SPs and the extension system doesn\u0027t support these structures being repeated like that anyway.  Everything here that\u0027s from the recipe page, and is not part of the specific trigger and stored function for the use case here, should be in a new file such as `neutron/db/migration/alembic_migrations/replaceable_obj.py`.","commit_id":"453bface8ef15a4e04533730d76f17b52f80d62c"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"4039a3e8942a9b0d5156a4ab0e01112a67b6a600","unresolved":false,"context_lines":[{"line_number":77,"context_line":")"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"class ReversibleOp(MigrateOperation):"},{"line_number":81,"context_line":"    def __init__(self, target):"},{"line_number":82,"context_line":"        self.target \u003d target"},{"line_number":83,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"dab17558_a45d1c49","line":80,"in_reply_to":"dab17558_4a3bbcd1","updated":"2016-05-10 06:39:49.000000000","message":"Thanks Mr.Mike. Let me expand your comment in my understanding:\n\n1. We should not place this file at this directory and should place /neutron/db/migration/alembic_migrations because some reasons as you wrote.\n\n2. I should modify some files such as: env.py and add as item 1 in oder that we can create \"function and trigger\" to the DB. After we modified, when we install Neutron project, it will add \"function and trigger\" to the DB backend. At this point, Neutron need to care for the type of backend DB such as: mysql postgresql,...  even if backend DB don\u0027t support that creating \"function and trigger\" feature then Neutron will not.\n\nThat\u0027s all my thinking after I read your comment. It that right? Please let me know if I misunderstand your comment.","commit_id":"453bface8ef15a4e04533730d76f17b52f80d62c"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"1a421d82a4dd3e65e60fe67c9df1993b2ef52a93","unresolved":false,"context_lines":[{"line_number":77,"context_line":")"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"class ReversibleOp(MigrateOperation):"},{"line_number":81,"context_line":"    def __init__(self, target):"},{"line_number":82,"context_line":"        self.target \u003d target"},{"line_number":83,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"dab17558_db158849","line":80,"in_reply_to":"dab17558_a45d1c49","updated":"2016-05-10 12:56:42.000000000","message":"im not sure if that\u0027s it.   let me try to be specific:\n\n1. class ReplaceableObject, class ReversibleOp, class CreateSPOp, class DropSPOp, class CreateTriggerOp, class DropTriggerOp, def create_sp, def create_trigger -\u003e  add to new file neutron/db/migration/alembic_migrations/replaceable_obj.py\n\n2. inside of neutron/db/migration/alembic_migrations/env.py -\u003e add \"from . import replaceable_obj\"\n\n3. the migration file here *stays*.   It should have: add_customer_sp, add_customer_trigger, def upgrade\n\n4. after we do that, we will need to add logic to switch for MySQL / Postgresql / others\n\nSo the next gerrit let\u0027s get #1, #2, #3 then we can figure out #4.\n\nhow\u0027s that?","commit_id":"453bface8ef15a4e04533730d76f17b52f80d62c"}],"neutron/db/migration/alembic_migrations/versions/newton/expand/cfbd4c516845_add_sp_and_trigger_for_cidr_overlap.py":[{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"bf8ab177ded3370ff9bb4c64e34043951f18bf03","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    $$"},{"line_number":93,"context_line":"    DECLARE msg VARCHAR(200);"},{"line_number":94,"context_line":"    BEGIN"},{"line_number":95,"context_line":"    IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id AND"},{"line_number":96,"context_line":"        cidr_overlap(cidr, NEW.cidr))) THEN"},{"line_number":97,"context_line":"        msg \u003d CONCAT("},{"line_number":98,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"}],"source_content_type":"text/x-python","patch_set":7,"id":"dab17558_06df75d6","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":6},"updated":"2016-05-17 12:24:20.000000000","message":"At this point, when there are two concurent requests:\n\nFor request 1: the network_id value doesn\u0027t has the value of request2 and cidr value doesn\u0027t has value of request 2\nFor request 2: It is similar.\n\nSo sometimes, this bug can reproduced. Do you have any suggetion for this case ?","commit_id":"18079c6ae2d1b014e54ab8e18ce7e4af441a317d"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"e09001572d779ec76f67ccd6dcd13ce99095c1e7","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    $$"},{"line_number":93,"context_line":"    DECLARE msg VARCHAR(200);"},{"line_number":94,"context_line":"    BEGIN"},{"line_number":95,"context_line":"    IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id AND"},{"line_number":96,"context_line":"        cidr_overlap(cidr, NEW.cidr))) THEN"},{"line_number":97,"context_line":"        msg \u003d CONCAT("},{"line_number":98,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"}],"source_content_type":"text/x-python","patch_set":7,"id":"dab17558_556be0f0","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":6},"in_reply_to":"dab17558_06df75d6","updated":"2016-05-17 13:57:21.000000000","message":"the transaction would have to be run under REPEATABLE READ isolation.  This is the default for MySQL but Postgresql defaults to READ COMMITTED.   This introduces another challenge to Neutron, because this setting must be made at the start of a transaction.  The new enginefacade system, for which there are other Gerrits for Neutron in review, has a transparent way of ensuring the current transaction is a certain isolation level, and if not a new transaction is started.  However until this work is merged, Neutron either needs to ensure this transaction is at REPEATABLE READ up front, or the method that makes use of this trigger must use a new Session with its own transaction.\n\nOnce we\u0027ve established how to gain control of the \"start\" of the transaction, the APIs for controlling isolation level  on a per-transaction basis in the ORM (assuming we aren\u0027t yet on new enginefacade, which handles this) are described at http://docs.sqlalchemy.org/en/rel_1_0/orm/session_transaction.html#setting-isolation-for-individual-transactions.   Neutron could also consider setting REPEATABLE READ isolation across the board however this is a more difficult change to make, as Postgresql is in general a little more aggressive about locking than MySQL so RR across the board may lead to new regressions.","commit_id":"18079c6ae2d1b014e54ab8e18ce7e4af441a317d"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"5fae6b46b915d4649714ceb77a16e269d99aa6f8","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    $$"},{"line_number":93,"context_line":"    DECLARE msg VARCHAR(200);"},{"line_number":94,"context_line":"    BEGIN"},{"line_number":95,"context_line":"    IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id AND"},{"line_number":96,"context_line":"        cidr_overlap(cidr, NEW.cidr))) THEN"},{"line_number":97,"context_line":"        msg \u003d CONCAT("},{"line_number":98,"context_line":"            \u0027inserted subnet \u0027, NEW.cidr,"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_62a54d03","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":6},"in_reply_to":"dab17558_556be0f0","updated":"2016-05-18 12:10:08.000000000","message":"Dear Mr.Mike\n\nThank you so much for your commment. I would like to update status after a hard working day. I am following your suggestion with 4 cases:\n\nCase 1: \n\nStep 1: I set \"REPEATABLE READ\" mode for Postgresql by modification postgresql.conf file to mode postgresql.conf [1]\nStep 2: Check transaction level [2]\n\nThen I reproduced this bug. Unluckily, the bug still happened. I wonder why this case is not similar to Mysql. \n\nCase 2: I changed Postgresql mode to \"SERIALIZABLE\"\n\nThe result is that this bug did not occur.\n\nCase 3: I\u0027ve modified \"no_overlap_cidr_subnets\" function for trigger as below:\n\"\"\"\n\tRETURNS TRIGGER AS\n    $$\n    DECLARE msg VARCHAR(200);\n    BEGIN\n    SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;\n    IF (EXISTS(SELECT * FROM subnets WHERE network_id \u003d NEW.network_id AND\n        cidr_overlap(cidr, NEW.cidr))) THEN\n        msg \u003d CONCAT(\n            \u0027inserted subnet \u0027, NEW.cidr,\n            \u0027 conflicts with existing subnets\u0027);\n        RAISE EXCEPTION  USING message \u003d msg, ERRCODE \u003d \u0027XX000\u0027;\n    END IF;\n    RETURN NEW;\n    END;\n    $$ LANGUAGE plpgsql\n\"\"\"\nThe result was similar to case 2.\n\n\nHowever, with case 2\u00263. When I check log file, sometimes it reported as expected and sometimes it reported  that the system could not serialize access due to concurrent update [3]. In my option, this is not so good\n\nCase 4: Create new Session for method use of this trigger\n\nSorry for your bother but could you please say more detail, I am trying to apply your idea but it is not success.\n\n[1] http://prnt.sc/b5h6lt\n[2] http://paste.openstack.org/show/497491/\n[3] http://paste.openstack.org/show/497489/","commit_id":"18079c6ae2d1b014e54ab8e18ce7e4af441a317d"}],"neutron/db/migration/alembic_migrations/versions/newton/expand/eb1c674f1322_add_sp_and_trigger_for_cidr_overlap.py":[{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"0e45cd3d123d068f04a6f3a41eff1208afb660a8","unresolved":false,"context_lines":[{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    cidr_inet_1 \u003d cast(split_part(cidr1, \u0027/\u0027, 1) as inet);"},{"line_number":89,"context_line":"    cidr_inet_2 \u003d cast(split_part(cidr2, \u0027/\u0027, 1) as inet);"},{"line_number":90,"context_line":"    IF FAMILY(cidr_inet_1) \u003d 6 THEN cidr_inet_1 \u003d NULL;"},{"line_number":91,"context_line":"    END IF;"},{"line_number":92,"context_line":"    IF FAMILY(cidr_inet_2) \u003d 6 THEN cidr_inet_2 \u003d NULL;"},{"line_number":93,"context_line":"    END IF;"}],"source_content_type":"text/x-python","patch_set":6,"id":"dab17558_9c583ffc","line":90,"range":{"start_line":90,"start_character":4,"end_line":90,"end_character":6},"updated":"2016-05-14 10:35:06.000000000","message":"The \"inet_aton\" of Mysql will return NULL if input is not \"Ipv4\" so in case I wrote to it will return NULL in Postgresql","commit_id":"e6d764573669483168779b6fbe4d88f925c1d189"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"0e45cd3d123d068f04a6f3a41eff1208afb660a8","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    IF FAMILY(cidr_inet_2) \u003d 6 THEN cidr_inet_2 \u003d NULL;"},{"line_number":93,"context_line":"    END IF;"},{"line_number":94,"context_line":"    RETURN"},{"line_number":95,"context_line":"    (cidr_inet_1 - \u00270.0.0.0\u0027::inet) \u0026 ~bitmask \u003d"},{"line_number":96,"context_line":"    (cidr_inet_2 - \u00270.0.0.0\u0027::inet) \u0026 ~bitmask;"},{"line_number":97,"context_line":"    END;"},{"line_number":98,"context_line":"    $$ LANGUAGE plpgsql;"}],"source_content_type":"text/x-python","patch_set":6,"id":"dab17558_dc4be729","line":95,"range":{"start_line":95,"start_character":4,"end_line":95,"end_character":5},"updated":"2016-05-14 10:35:06.000000000","message":"Because: Postgresql don\u0027t have \"inet_aton\" function so this coding is similar.","commit_id":"e6d764573669483168779b6fbe4d88f925c1d189"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"0e45cd3d123d068f04a6f3a41eff1208afb660a8","unresolved":false,"context_lines":[{"line_number":133,"context_line":"    if op.get_bind().engine.name \u003d\u003d \u0027mysql\u0027:"},{"line_number":134,"context_line":"        op.create_sp(add_stored_procedure_for_mysql)"},{"line_number":135,"context_line":"        op.create_trigger(add_trigger_for_mysql)"},{"line_number":136,"context_line":"    elif op.get_bind().engine.name \u003d\u003d \u0027postgresql\u0027:"},{"line_number":137,"context_line":"        op.create_sp(add_stored_procedure_1_for_postgresql)"},{"line_number":138,"context_line":"        op.create_sp(add_stored_procedure_2_for_postgresql)"},{"line_number":139,"context_line":"        op.create_trigger(add_trigger_for_postgresql)"}],"source_content_type":"text/x-python","patch_set":6,"id":"dab17558_7c12bb0a","line":136,"updated":"2016-05-14 10:35:06.000000000","message":"I think that the structure of Postgresql is a little deferent from Mysql so I need to test again, actually it is not really active as we expect.","commit_id":"e6d764573669483168779b6fbe4d88f925c1d189"}],"neutron/db/migration/alembic_migrations/versions/newton/expand/fcde86592659_add_stored_procedure_and_trigger_for_.py":[{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"90a37069c80f25c44b68425c968e5a55b24c9833","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":38,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":39,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":"    RETURNS TINYINT"}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_ef4bd257","line":38,"range":{"start_line":38,"start_character":4,"end_line":38,"end_character":5},"updated":"2016-06-06 11:23:41.000000000","message":"Dear Mr.Mile, Mr.Assaf, Mr.Sean, Motoki-san.\n\n\nI would like explain this solution to make it easy. The proof of concept for this solution is that we are trying to bit masking from left to right for both CIDRs. If it is fully matched, It means CIDRs are overlapping.","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"712d10805780bbd262c694b35f5c336ccd34e3e0","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":38,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":39,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":"    RETURNS TINYINT"}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_1ea0e442","line":38,"in_reply_to":"7aa08908_678d3b31","updated":"2016-06-07 03:17:45.000000000","message":"Dear Mr.Sean\n\nThank you for your time. Please understand me. I just would like to explain my solution to you to make more easy for understanding, because you said \"This make my head hurt\".I do want everthing that is better.\n\n\u003e I don\u0027t think we should be adding a stored procedure.\n\nCurrently, I had another patch set to fix this bug. But Mr.Kevin don\u0027t like it so I push this solution which was supported by Mr.Mike and Mr.Kevin.\n\n\u003e  Not one that has no testing, zero comments, and also has been revised by the author after issues were found. This is not maintainable.\n\nYes, It is truth. This is not final patch, I just want to get estimate from the core-review (like you). But in fact, I don\u0027t have idea yet for functional and unit-test. I will be very grateful if you could give me suggestion to do it. Thanks Mr.Sean","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":4656,"name":"Sean M. Collins","email":"sean@coreitpro.com","username":"scollins"},"change_message_id":"417b67c6d6edb636bace9e651e3429669d1b4b04","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"add_stored_procedure_for_mysql \u003d replaceable_obj.ReplaceableObject("},{"line_number":38,"context_line":"    \"cidr_overlap(cidr1 varchar(64), ip_version_1 tinyint, \""},{"line_number":39,"context_line":"    \"cidr2 varchar(64), ip_version_2 tinyint)\","},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":"    RETURNS TINYINT"}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_678d3b31","line":38,"in_reply_to":"7aa08908_ef4bd257","updated":"2016-06-06 14:32:17.000000000","message":"Adding comments to the *review* to explain this is completely useless. This will never be consulted if someone has to debug this.","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"90a37069c80f25c44b68425c968e5a55b24c9833","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    DECLARE ipv6_1, ipv6_2, bitmask INT;"},{"line_number":44,"context_line":"    DECLARE division, modulo, netmask SMALLINT;"},{"line_number":45,"context_line":"    DECLARE tmp TINYINT DEFAULT 1;"},{"line_number":46,"context_line":"    SET netmask \u003d least("},{"line_number":47,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":48,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":49,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_afdd4a72","line":46,"updated":"2016-06-06 11:23:41.000000000","message":"\"netmask\" parameter is minimun of two netmask.","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"90a37069c80f25c44b68425c968e5a55b24c9833","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    SET netmask \u003d least("},{"line_number":47,"context_line":"                cast(substring_index(cidr1, \u0027/\u0027, -1) as signed integer),"},{"line_number":48,"context_line":"                cast(substring_index(cidr2, \u0027/\u0027, -1) as signed integer));"},{"line_number":49,"context_line":"    IF (ip_version_1 \u003d 6 AND ip_version_2 \u003d 6) THEN"},{"line_number":50,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":51,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":52,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_af4b8a2a","line":49,"range":{"start_line":49,"start_character":4,"end_line":49,"end_character":6},"updated":"2016-06-06 11:23:41.000000000","message":"For IPv6. There is a little bit special. I just compare 16 bits a time because mysql cannot support to compare bigger 64 bits.","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"90a37069c80f25c44b68425c968e5a55b24c9833","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        SET division \u003d netmask DIV 16;"},{"line_number":51,"context_line":"        SET modulo \u003d netmask % 16;"},{"line_number":52,"context_line":"        masking : WHILE (division \u003e\u003d 0) DO"},{"line_number":53,"context_line":"            SET ipv6_1 \u003d CONV(substring_index(substring_index"},{"line_number":54,"context_line":"                                    (cidr1, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10);"},{"line_number":55,"context_line":"            SET ipv6_2 \u003d CONV(substring_index(substring_index"},{"line_number":56,"context_line":"                                    (cidr2, \u0027:\u0027, tmp), \u0027:\u0027, -1), 16, 10);"}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_6fab628a","line":53,"range":{"start_line":53,"start_character":12,"end_line":53,"end_character":15},"updated":"2016-06-06 11:23:41.000000000","message":"ipv6_1 is 4 characters for a loop.\nFor example: \u0027abcd:123a:456b:789c\u0027\nLoop 1: ipv6 \u003d \u0027abcd\u0027\nLoop 2: ipv6 \u003d \u0027123a\u0027\nLoop 3: ipv6 \u003d \u0027456b\u0027\n...","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"90a37069c80f25c44b68425c968e5a55b24c9833","unresolved":false,"context_lines":[{"line_number":60,"context_line":"                    LEAVE masking;"},{"line_number":61,"context_line":"                END IF;"},{"line_number":62,"context_line":"            ELSE"},{"line_number":63,"context_line":"                SET bitmask \u003d pow(2, (16 - modulo)) - 1;"},{"line_number":64,"context_line":"                RETURN ipv6_1 \u0026 ~bitmask \u003d ipv6_2 \u0026 ~bitmask;"},{"line_number":65,"context_line":"            END IF;"},{"line_number":66,"context_line":"            SET tmp \u003d tmp + 1;"}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_4f8826e8","line":63,"updated":"2016-06-06 11:23:41.000000000","message":"This is final loop. So it contents bits of network and bit of address. So it is similar to IPv4.","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"90a37069c80f25c44b68425c968e5a55b24c9833","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    ELSE"},{"line_number":70,"context_line":"        SET bitmask \u003d pow(2, 32 - netmask) - 1;"},{"line_number":71,"context_line":"        RETURN"},{"line_number":72,"context_line":"            inet_aton(substring_index(cidr1, \u0027/\u0027, 1)) \u0026 ~bitmask \u003d"},{"line_number":73,"context_line":"            inet_aton(substring_index(cidr2, \u0027/\u0027, 1)) \u0026 ~bitmask;"},{"line_number":74,"context_line":"    END IF;"},{"line_number":75,"context_line":"    END"}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_b272d17a","line":72,"range":{"start_line":72,"start_character":57,"end_line":72,"end_character":64},"updated":"2016-06-06 11:23:41.000000000","message":"inet_aton: Given the dotted-quad representation of an IPv4 network address as a string, returns an integer that represents the numeric value of the address in network byte order (big endian)\n\nFox example: INET_ATON(\u002710.0.5.9\u0027) will return: 167773449\n\n~bitmask: Bitwise inversion","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"a269907b3d067edbfd304a98043fb289b7b1d634","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":106,"context_line":"            # NOTE(namnh): This feature is available for Postgresql 9.4 and"},{"line_number":107,"context_line":"            # higher versions."},{"line_number":108,"context_line":"            op.execute(\"CREATE EXTENSION btree_gist\")"},{"line_number":109,"context_line":"            op.execute(\"ALTER TABLE subnets ADD CONSTRAINT \""},{"line_number":110,"context_line":"                       \"no_overlap_cidr_subnets EXCLUDE USING \""},{"line_number":111,"context_line":"                       \"gist((cast(cidr AS CIDR)) inet_ops WITH \u0026\u0026, \""}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_3392bc4c","line":108,"updated":"2016-06-08 15:48:47.000000000","message":"this should probably be \"CREATE EXTENSION IF NOT EXISTS btree_gist\"","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"b143164dbdd314e4e5f4cfffe2e8ab753e03cc6b","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        if op.get_bind().engine.dialect.server_version_info \u003e\u003d (9, 4, 0):"},{"line_number":106,"context_line":"            # NOTE(namnh): This feature is available for Postgresql 9.4 and"},{"line_number":107,"context_line":"            # higher versions."},{"line_number":108,"context_line":"            op.execute(\"CREATE EXTENSION btree_gist\")"},{"line_number":109,"context_line":"            op.execute(\"ALTER TABLE subnets ADD CONSTRAINT \""},{"line_number":110,"context_line":"                       \"no_overlap_cidr_subnets EXCLUDE USING \""},{"line_number":111,"context_line":"                       \"gist((cast(cidr AS CIDR)) inet_ops WITH \u0026\u0026, \""}],"source_content_type":"text/x-python","patch_set":12,"id":"7aa08908_5772a64a","line":108,"in_reply_to":"7aa08908_3392bc4c","updated":"2016-06-09 10:50:55.000000000","message":"Thank you Mr.Mike. Surely, I will update it.","commit_id":"d17ca591f19dfa9c8221fe13e875da9398dda5a2"}],"neutron/db/models_v2.py":[{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"a08e5edecb85e1e672b2e0a288f9c1064d7474c4","unresolved":false,"context_lines":[{"line_number":228,"context_line":"        foreign_keys\u003d\u0027Subnet.network_id\u0027,"},{"line_number":229,"context_line":"        primaryjoin\u003d\u0027Subnet.network_id\u003d\u003dNetworkRBAC.object_id\u0027)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"sqla_event.listen("},{"line_number":232,"context_line":"    Subnet.__table__, \"after_create\","},{"line_number":233,"context_line":"    sa.DDL("},{"line_number":234,"context_line":"    \"\"\"CREATE FUNCTION"}],"source_content_type":"text/x-python","patch_set":23,"id":"3aaa91ec_fb29e68a","line":231,"updated":"2016-06-27 18:46:27.000000000","message":"unfortunately, the source of the SP must be stated separately in the model and in the migration.  If/when the SP were changed in a future release, the text here would diverge from the text that\u0027s frozen in the migration file.\n\n*unless* we change the opportunistic test fixture itself to always use migrations to build up the DB.  I\u0027ve proposed doing that on the dependent review here.\n\nIn that case, the SP source code here as stated would never be used and would be safe to remove, provided that there\u0027s no desire for any self-documenation of DB functionality here.","commit_id":"41f925380573f714d6f5e3fdd511ae650069f878"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"2b0de352e994010f3bfd25bb8f8d76fa6a64cd90","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        foreign_keys\u003d\u0027Subnet.network_id\u0027,"},{"line_number":226,"context_line":"        primaryjoin\u003d\u0027Subnet.network_id\u003d\u003dNetworkRBAC.object_id\u0027)"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"sqla_event.listen("},{"line_number":229,"context_line":"    Subnet.__table__, \"after_create\","},{"line_number":230,"context_line":"    sa.DDL("},{"line_number":231,"context_line":"        \"\"\"CREATE FUNCTION"}],"source_content_type":"text/x-python","patch_set":29,"id":"bacf61ea_44ac66a0","line":228,"updated":"2016-07-28 15:27:05.000000000","message":"so the good news is that I think we will be able to take all of this out of the models, as the test suite refactor I\u0027m working on (https://review.openstack.org/#/c/347609/) will allow Neutron to run all PG/MySQL tests using the alembic migrations to build up the DB.  that is, we won\u0027t rely upon create_all() for them.","commit_id":"0f3a3aa341e7a01e0f175e777792bc0ce35776b7"}],"neutron/tests/functional/db/test_function.py":[{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"19aad040fb655cc84267d4e5a498e8acff8c4673","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        engine \u003d self.get_engine()"},{"line_number":49,"context_line":"        with engine.connect() as connection:"},{"line_number":50,"context_line":"            cfg.CONF.set_override(\u0027connection\u0027, engine.url, group\u003d\u0027database\u0027)"},{"line_number":51,"context_line":"            migration.do_alembic_command(self.alembic_config, \u0027upgrade\u0027,"},{"line_number":52,"context_line":"                                         \u0027heads\u0027)"},{"line_number":53,"context_line":"            for ip_1, ip_version_1, ip_2, ip_version_2, expected in ["},{"line_number":54,"context_line":"                (\u0027192.168.1.0/24\u0027, \u00274\u0027, \u0027192.168.2.0/24\u0027, \u00274\u0027, 0),"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a9d85d2_3d63561c","line":51,"updated":"2016-06-20 16:02:00.000000000","message":"is this UPGRADE needed here?  why isn\u0027t the database on the latest version when the tests run?","commit_id":"a57a4d31f2345c89a4bbf56787dd2ef808f99157"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"8898bf758dfb66f6d788a9e1691c9b317b6cc24a","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        engine \u003d self.get_engine()"},{"line_number":49,"context_line":"        with engine.connect() as connection:"},{"line_number":50,"context_line":"            cfg.CONF.set_override(\u0027connection\u0027, engine.url, group\u003d\u0027database\u0027)"},{"line_number":51,"context_line":"            migration.do_alembic_command(self.alembic_config, \u0027upgrade\u0027,"},{"line_number":52,"context_line":"                                         \u0027heads\u0027)"},{"line_number":53,"context_line":"            for ip_1, ip_version_1, ip_2, ip_version_2, expected in ["},{"line_number":54,"context_line":"                (\u0027192.168.1.0/24\u0027, \u00274\u0027, \u0027192.168.2.0/24\u0027, \u00274\u0027, 0),"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a9d85d2_7f02c40c","line":51,"in_reply_to":"5a9d85d2_3d63561c","updated":"2016-06-21 12:31:00.000000000","message":"Yes, this is. I also commented this lines but at that time, it reported \"the function doesn\u0027t exsit\". That\u0027s mean DB is not on the lastest version.\n\nBy the way, could you please spend some minutes to care for the algorithm to detect overlap IPv6. How do you think about that.","commit_id":"a57a4d31f2345c89a4bbf56787dd2ef808f99157"}],"neutron/tests/functional/db/test_migrations.py":[{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"94c3ec463a8771342a1fd5d6a588eb93e7b38fef","unresolved":false,"context_lines":[{"line_number":65,"context_line":""},{"line_number":66,"context_line":"        mysql -u root"},{"line_number":67,"context_line":"        \u003ecreate database openstack_citest;"},{"line_number":68,"context_line":"        \u003egrant all privileges on openstack_citest.* to"},{"line_number":69,"context_line":"         openstack_citest@localhost identified by \u0027openstack_citest\u0027;"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    Output is a list that contains information about differences between db and"}],"source_content_type":"text/x-python","patch_set":14,"id":"7aa08908_37539a6e","line":68,"range":{"start_line":68,"start_character":33,"end_line":68,"end_character":51},"updated":"2016-06-09 10:52:49.000000000","message":"I think that at this point, it should be changed to \"grant all privileges on *.* to openstack_citest@localhost identified by \u0027openstack_citest\u0027;\". \n\nBecause when I run funtional-test on test_migrations.py file, it always reports error that \"sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1044, u\"Access denied for user \u0027openstack_citest\u0027@\u0027localhost\u0027 to database \u0027txgfbjuwwe\u0027\") [SQL: \u0027CREATE DATABASE txgfbjuwwe\u0027]\". \nHow do you think?","commit_id":"327e42a26073d18484057192ce99ff99e65857ef"}],"neutron/tests/functional/db/test_serverside_fn.py":[{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"120dbacffdc8f14332ca884e1ef43ce2d716e1aa","unresolved":false,"context_lines":[{"line_number":40,"context_line":"                                 \"failure: %s %s\" % (ip_1, ip_2))"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    # def test_insert_trigger(self):"},{"line_number":43,"context_line":"        # TODO:"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"# class PostgresqlSSTestCase(testlib_api.PostgreSQLTestCaseMixin,"},{"line_number":46,"context_line":"#                            ServerSideTestCase):"}],"source_content_type":"text/x-python","patch_set":23,"id":"1aa78d24_2cd84653","line":43,"range":{"start_line":43,"start_character":8,"end_line":43,"end_character":15},"updated":"2016-07-04 11:17:08.000000000","message":"At this point, do I need to write for those function?","commit_id":"41f925380573f714d6f5e3fdd511ae650069f878"}],"neutron/tests/functional/db/test_trigger.py":[{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"a51ede9cbc259f82a88867786c3e57aa0587fa19","unresolved":false,"context_lines":[{"line_number":5,"context_line":"from oslo_config import fixture as config_fixture"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"class TestTriggerMysql(base.MySQLTestCase):"},{"line_number":9,"context_line":"    \u0027\u0027\u0027Test for checking of equality models state and migrations."},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"        For the opportunistic testing you need to set up a db named"}],"source_content_type":"text/x-python","patch_set":15,"id":"7aa08908_4371f643","line":8,"range":{"start_line":8,"start_character":0,"end_line":8,"end_character":5},"updated":"2016-06-10 15:22:33.000000000","message":"Dear Mr.Mike, Mr.Sean, Mr.Assaf, Motoki-san\n\nI wrote function for this trigger. How do you think about this?","commit_id":"048734bbb6c8f02d19899708e4b510989bb89f8d"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"8c06a83cc1825964b751c5903c61336e07a7fb71","unresolved":false,"context_lines":[{"line_number":14,"context_line":"        The test will then use that db and user/password combo to run the tests."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"        For MySQL on Ubuntu this can be done with the following commands::"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"            mysql -u root"},{"line_number":19,"context_line":"            \u003ecreate database openstack_citest;"},{"line_number":20,"context_line":"            \u003egrant all privileges on openstack_citest.* to"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_781e1871","line":17,"updated":"2016-06-13 14:41:17.000000000","message":"would this also need \"opportunistic\" logic to ensure that we\u0027re on a high enough version of MySQL / MariaDB ?   e.g. if on mysql 5.6 we\u0027d need to skiptest on this.","commit_id":"0dd5adf4cff19cccada366ff8c70c48fc22edbb1"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"af0dadc4a62eb426412f5209566dc8f88b9f5f35","unresolved":false,"context_lines":[{"line_number":14,"context_line":"        The test will then use that db and user/password combo to run the tests."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"        For MySQL on Ubuntu this can be done with the following commands::"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"            mysql -u root"},{"line_number":19,"context_line":"            \u003ecreate database openstack_citest;"},{"line_number":20,"context_line":"            \u003egrant all privileges on openstack_citest.* to"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_b6335061","line":17,"in_reply_to":"7aa08908_781e1871","updated":"2016-06-14 07:11:17.000000000","message":"Thank you so much for your comment. \n\nI will modify this docstring. Please refer to next patch, if I don\u0027t catch your idea, please you remind me.","commit_id":"0dd5adf4cff19cccada366ff8c70c48fc22edbb1"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"8c06a83cc1825964b751c5903c61336e07a7fb71","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        engine \u003d self.get_engine()"},{"line_number":35,"context_line":"        with engine.connect() as connection:"},{"line_number":36,"context_line":"            cfg.CONF.set_override(\u0027connection\u0027, engine.url, group\u003d\u0027database\u0027)"},{"line_number":37,"context_line":"            self.alembic_config.attributes[\u0027connection\u0027] \u003d connection"},{"line_number":38,"context_line":"            migration.do_alembic_command(self.alembic_config, \u0027upgrade\u0027,"},{"line_number":39,"context_line":"                                         \u0027heads\u0027)"},{"line_number":40,"context_line":"            result \u003d (connection.execute(\"select cidr_overlap(\""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_98ef8486","line":37,"updated":"2016-06-13 14:41:17.000000000","message":"isn\u0027t it a given that the database would be upgraded to the latest schema before the test suite is run?   I\u0027m not a neutron person but I\u0027m pretty sure we don\u0027t need to have alembic stuff in these tests?","commit_id":"0dd5adf4cff19cccada366ff8c70c48fc22edbb1"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"af0dadc4a62eb426412f5209566dc8f88b9f5f35","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        engine \u003d self.get_engine()"},{"line_number":35,"context_line":"        with engine.connect() as connection:"},{"line_number":36,"context_line":"            cfg.CONF.set_override(\u0027connection\u0027, engine.url, group\u003d\u0027database\u0027)"},{"line_number":37,"context_line":"            self.alembic_config.attributes[\u0027connection\u0027] \u003d connection"},{"line_number":38,"context_line":"            migration.do_alembic_command(self.alembic_config, \u0027upgrade\u0027,"},{"line_number":39,"context_line":"                                         \u0027heads\u0027)"},{"line_number":40,"context_line":"            result \u003d (connection.execute(\"select cidr_overlap(\""}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_7cdc2ce4","line":37,"in_reply_to":"7aa08908_98ef8486","updated":"2016-06-14 07:11:17.000000000","message":"Yes, you are right. I removed the line on my local, it\u0027s still ok. I will remove it in next patch.","commit_id":"0dd5adf4cff19cccada366ff8c70c48fc22edbb1"},{"author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"change_message_id":"8c06a83cc1825964b751c5903c61336e07a7fb71","unresolved":false,"context_lines":[{"line_number":43,"context_line":"            for row in result:"},{"line_number":44,"context_line":"                self.assertEqual(row[0], 1)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def test_no_overlap_ipv4(self):"},{"line_number":47,"context_line":"        engine \u003d self.get_engine()"},{"line_number":48,"context_line":"        with engine.connect() as connection:"},{"line_number":49,"context_line":"            self.alembic_config.attributes[\u0027connection\u0027] \u003d connection"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_c2ee3621","line":46,"updated":"2016-06-13 14:41:17.000000000","message":"this is a lot of boilerplate for the test that\u0027s basically \"fn(x, y) \u003d\u003d z\", maybe we could organize this as a \"data table\" type of test?  that is:\n\n    for ip1, ip2, expected in [\n          (\u0027192.168.1.0/24\u0027, \u0027192.168.2.0.24\u0027, False),\n          ( ... ) ,\n          ...\n    ]:\n        result \u003d conn.scalar(\"select cidr_overlap(..., ...)\")\n        self.assertEqual(result, expected, \"failure: %s %s \" % (ip1, ip2))","commit_id":"0dd5adf4cff19cccada366ff8c70c48fc22edbb1"},{"author":{"_account_id":19554,"name":"Nam","email":"namnh68@fsoft.com.vn","username":"namnh"},"change_message_id":"af0dadc4a62eb426412f5209566dc8f88b9f5f35","unresolved":false,"context_lines":[{"line_number":43,"context_line":"            for row in result:"},{"line_number":44,"context_line":"                self.assertEqual(row[0], 1)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def test_no_overlap_ipv4(self):"},{"line_number":47,"context_line":"        engine \u003d self.get_engine()"},{"line_number":48,"context_line":"        with engine.connect() as connection:"},{"line_number":49,"context_line":"            self.alembic_config.attributes[\u0027connection\u0027] \u003d connection"}],"source_content_type":"text/x-python","patch_set":17,"id":"7aa08908_b6a350ff","line":46,"in_reply_to":"7aa08908_c2ee3621","updated":"2016-06-14 07:11:17.000000000","message":"Yes, good comment. This will increase performance of this test. Surely, I will update this in my patch. Thanks Mr.Mike.\n\nOne more things, Because the result of \"cidr_overlap\" function is 0 and 1. So I will modify from False to 0 and \"True\" to 1.","commit_id":"0dd5adf4cff19cccada366ff8c70c48fc22edbb1"}]}
